Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(208)

Side by Side Diff: pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart

Issue 1458703007: dart2js cps: Refactor CallExpressions into Primitives. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library tree_ir_builder; 5 library tree_ir_builder;
6 6
7 import '../common.dart'; 7 import '../common.dart';
8 import '../constants/values.dart'; 8 import '../constants/values.dart';
9 import '../cps_ir/cps_ir_nodes.dart' as cps_ir; 9 import '../cps_ir/cps_ir_nodes.dart' as cps_ir;
10 import '../elements/elements.dart'; 10 import '../elements/elements.dart';
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 if (thisParameter != null && reference.definition == thisParameter) { 110 if (thisParameter != null && reference.definition == thisParameter) {
111 return new This(); 111 return new This();
112 } 112 }
113 return new VariableUse(getVariable(reference.definition)); 113 return new VariableUse(getVariable(reference.definition));
114 } 114 }
115 115
116 Label getLabel(cps_ir.Continuation cont) { 116 Label getLabel(cps_ir.Continuation cont) {
117 return labels.putIfAbsent(cont, () => new Label()); 117 return labels.putIfAbsent(cont, () => new Label());
118 } 118 }
119 119
120 Variable addFunctionParameter(cps_ir.Definition variable) { 120 Variable addFunctionParameter(cps_ir.Parameter parameter) {
121 if (variable is cps_ir.Parameter) { 121 return getVariable(parameter);
122 return getVariable(variable);
123 } else {
124 return addMutableVariable(variable as cps_ir.MutableVariable)
125 ..isCaptured = true;
126 }
127 } 122 }
128 123
129 FunctionDefinition buildFunction(cps_ir.FunctionDefinition node) { 124 FunctionDefinition buildFunction(cps_ir.FunctionDefinition node) {
130 currentElement = node.element; 125 currentElement = node.element;
131 if (parent != null) { 126 if (parent != null) {
132 // Local function's 'this' refers to enclosing method's 'this' 127 // Local function's 'this' refers to enclosing method's 'this'
133 thisParameter = parent.thisParameter; 128 thisParameter = parent.thisParameter;
134 } else { 129 } else {
135 thisParameter = node.thisParameter; 130 thisParameter = node.thisParameter;
136 } 131 }
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 Statement result = node.accept(this); // Translate the tail expression. 261 Statement result = node.accept(this); // Translate the tail expression.
267 for (NodeCallback fun in stack.reversed) { 262 for (NodeCallback fun in stack.reversed) {
268 result = fun(result); 263 result = fun(result);
269 } 264 }
270 return result; 265 return result;
271 } 266 }
272 267
273 /// Translates a CPS primitive to a tree expression. 268 /// Translates a CPS primitive to a tree expression.
274 /// 269 ///
275 /// This simply calls the visit method for the primitive. 270 /// This simply calls the visit method for the primitive.
276 Expression translatePrimitive(cps_ir.Primitive prim) { 271 translatePrimitive(cps_ir.Primitive prim) {
277 return prim.accept(this); 272 return prim.accept(this);
278 } 273 }
279 274
280 /************************ INTERIOR EXPRESSIONS ************************/ 275 /************************ INTERIOR EXPRESSIONS ************************/
281 // 276 //
282 // Visit methods for interior expressions must return a function: 277 // Visit methods for interior expressions must return a function:
283 // 278 //
284 // (Statement next) => <result statement> 279 // (Statement next) => <result statement>
285 // 280 //
286 281
287 NodeCallback visitLetPrim(cps_ir.LetPrim node) => (Statement next) { 282 NodeCallback visitLetPrim(cps_ir.LetPrim node) {
288 Variable variable = getVariable(node.primitive); 283 Variable variable = getVariable(node.primitive);
289 Expression value = translatePrimitive(node.primitive); 284 var value = translatePrimitive(node.primitive);
290 if (node.primitive.hasAtLeastOneUse) { 285 if (value is Expression) {
291 return Assign.makeStatement(variable, value, next); 286 if (node.primitive.hasAtLeastOneUse) {
287 return (Statement next) => Assign.makeStatement(variable, value, next);
288 } else {
289 return (Statement next) => new ExpressionStatement(value, next);
290 }
292 } else { 291 } else {
293 return new ExpressionStatement(value, next); 292 assert(value is NodeCallback);
293 return value;
294 } 294 }
295 }; 295 }
296 296
297 // Continuations are bound at the same level, but they have to be 297 // Continuations are bound at the same level, but they have to be
298 // translated as if nested. This is because the body can invoke any 298 // translated as if nested. This is because the body can invoke any
299 // of them from anywhere, so it must be nested inside all of them. 299 // of them from anywhere, so it must be nested inside all of them.
300 // 300 //
301 // The continuation bodies are not always translated directly here because 301 // The continuation bodies are not always translated directly here because
302 // they may have been already translated: 302 // they may have been already translated:
303 // * For singly-used continuations, the continuation's body is 303 // * For singly-used continuations, the continuation's body is
304 // translated at the site of the continuation invocation. 304 // translated at the site of the continuation invocation.
305 // * For recursive continuations, there is a single non-recursive 305 // * For recursive continuations, there is a single non-recursive
(...skipping 26 matching lines...) Expand all
332 return new Try(next, catchParameters, catchBody); 332 return new Try(next, catchParameters, catchBody);
333 }; 333 };
334 334
335 NodeCallback visitLetMutable(cps_ir.LetMutable node) { 335 NodeCallback visitLetMutable(cps_ir.LetMutable node) {
336 Variable variable = addMutableVariable(node.variable); 336 Variable variable = addMutableVariable(node.variable);
337 Expression value = getVariableUse(node.value); 337 Expression value = getVariableUse(node.value);
338 return (Statement next) => Assign.makeStatement(variable, value, next); 338 return (Statement next) => Assign.makeStatement(variable, value, next);
339 } 339 }
340 340
341 341
342 /************************ CALL EXPRESSIONS ************************/ 342 /*********** PRIMITIVES that used to be CALL EXPRESSIONS ***************/
343 // 343 //
344 // Visit methods for call expressions must return a function: 344 // Visit methods for primitives must return an expression or a NodeCallback.
345 // 345 //
346 // (Statement next) => <result statement> 346 // Section kept here to make the diff look nicer.
347 // 347 //
348 // The result statement must include an assignment to the continuation 348 // FIXME(asgerf): Move down to other primitives.
349 // parameter, if the parameter is used.
350 // 349 //
351 350
352 NodeCallback makeCallExpression(cps_ir.CallExpression call, 351 Expression visitInvokeStatic(cps_ir.InvokeStatic node) {
353 Expression expression) { 352 List<Expression> arguments = translateArguments(node.arguments);
354 return (Statement next) { 353 return new InvokeStatic(node.target, node.selector, arguments,
355 cps_ir.Parameter result = call.continuation.definition.parameters.single; 354 node.sourceInformation);
356 if (result.hasAtLeastOneUse) {
357 return Assign.makeStatement(getVariable(result), expression, next);
358 } else {
359 return new ExpressionStatement(expression, next);
360 }
361 };
362 } 355 }
363 356
364 NodeCallback visitInvokeStatic(cps_ir.InvokeStatic node) { 357 Expression visitInvokeMethod(cps_ir.InvokeMethod node) {
365 List<Expression> arguments = translateArguments(node.arguments);
366 Expression invoke = new InvokeStatic(node.target, node.selector, arguments,
367 node.sourceInformation);
368 return makeCallExpression(node, invoke);
369 }
370
371 NodeCallback visitInvokeMethod(cps_ir.InvokeMethod node) {
372 InvokeMethod invoke = new InvokeMethod( 358 InvokeMethod invoke = new InvokeMethod(
373 getVariableUse(node.receiver), 359 getVariableUse(node.receiver),
374 node.selector, 360 node.selector,
375 node.mask, 361 node.mask,
376 translateArguments(node.arguments), 362 translateArguments(node.arguments),
377 node.sourceInformation); 363 node.sourceInformation);
378 invoke.receiverIsNotNull = node.receiverIsNotNull; 364 invoke.receiverIsNotNull = node.receiverIsNotNull;
379 return makeCallExpression(node, invoke); 365 return invoke;
380 } 366 }
381 367
382 NodeCallback visitInvokeMethodDirectly(cps_ir.InvokeMethodDirectly node) { 368 Expression visitInvokeMethodDirectly(cps_ir.InvokeMethodDirectly node) {
383 Expression receiver = getVariableUse(node.receiver); 369 Expression receiver = getVariableUse(node.receiver);
384 List<Expression> arguments = translateArguments(node.arguments); 370 List<Expression> arguments = translateArguments(node.arguments);
385 Expression invoke = new InvokeMethodDirectly(receiver, node.target, 371 return new InvokeMethodDirectly(receiver, node.target,
386 node.selector, arguments, node.sourceInformation); 372 node.selector, arguments, node.sourceInformation);
387 return makeCallExpression(node, invoke);
388 } 373 }
389 374
390 NodeCallback visitTypeCast(cps_ir.TypeCast node) { 375 Expression visitTypeCast(cps_ir.TypeCast node) {
391 Expression value = getVariableUse(node.value); 376 Expression value = getVariableUse(node.value);
392 List<Expression> typeArgs = translateArguments(node.typeArguments); 377 List<Expression> typeArgs = translateArguments(node.typeArguments);
393 Expression expression = 378 return new TypeOperator(value, node.dartType, typeArgs, isTypeTest: false);
394 new TypeOperator(value, node.dartType, typeArgs, isTypeTest: false);
395 return makeCallExpression(node, expression);
396 } 379 }
397 380
398 NodeCallback visitInvokeConstructor(cps_ir.InvokeConstructor node) { 381 Expression visitInvokeConstructor(cps_ir.InvokeConstructor node) {
399 List<Expression> arguments = translateArguments(node.arguments); 382 List<Expression> arguments = translateArguments(node.arguments);
400 Expression invoke = new InvokeConstructor( 383 return new InvokeConstructor(
401 node.dartType, 384 node.dartType,
402 node.target, 385 node.target,
403 node.selector, 386 node.selector,
404 arguments, 387 arguments,
405 node.sourceInformation); 388 node.sourceInformation);
406 return makeCallExpression(node, invoke);
407 } 389 }
408 390
409 NodeCallback visitForeignCode(cps_ir.ForeignCode node) { 391 visitForeignCode(cps_ir.ForeignCode node) {
410 List<Expression> arguments = 392 List<Expression> arguments =
411 node.arguments.map(getVariableUse).toList(growable: false); 393 node.arguments.map(getVariableUse).toList(growable: false);
412 if (HasCapturedArguments.check(node.codeTemplate.ast)) { 394 if (HasCapturedArguments.check(node.codeTemplate.ast)) {
413 for (Expression arg in arguments) { 395 for (Expression arg in arguments) {
414 if (arg is VariableUse) { 396 if (arg is VariableUse) {
415 arg.variable.isCaptured = true; 397 arg.variable.isCaptured = true;
416 } else { 398 } else {
417 // TODO(asgerf): Avoid capture of 'this'. 399 // TODO(asgerf): Avoid capture of 'this'.
418 } 400 }
419 } 401 }
420 } 402 }
421 if (node.codeTemplate.isExpression) { 403 if (node.codeTemplate.isExpression) {
422 Expression foreignCode = new ForeignExpression( 404 return new ForeignExpression(
423 node.codeTemplate, 405 node.codeTemplate,
424 node.type, 406 node.type,
425 arguments, 407 arguments,
426 node.nativeBehavior, 408 node.nativeBehavior,
427 node.dependency); 409 node.dependency);
428 return makeCallExpression(node, foreignCode);
429 } else { 410 } else {
430 return (Statement next) { 411 return (Statement next) {
431 assert(next is Unreachable); // We are not using the `next` statement. 412 assert(next is Unreachable); // We are not using the `next` statement.
432 return new ForeignStatement( 413 return new ForeignStatement(
433 node.codeTemplate, 414 node.codeTemplate,
434 node.type, 415 node.type,
435 arguments, 416 arguments,
436 node.nativeBehavior, 417 node.nativeBehavior,
437 node.dependency); 418 node.dependency);
438 }; 419 };
439 } 420 }
440 } 421 }
441 422
442 NodeCallback visitGetLazyStatic(cps_ir.GetLazyStatic node) { 423 Expression visitGetLazyStatic(cps_ir.GetLazyStatic node) {
443 // In the tree IR, GetStatic handles lazy fields because we do not need 424 // In the tree IR, GetStatic handles lazy fields because we do not need
444 // as fine-grained control over side effects. 425 // as fine-grained control over side effects.
445 GetStatic value = new GetStatic(node.element, node.sourceInformation); 426 return new GetStatic(node.element, node.sourceInformation);
446 return makeCallExpression(node, value);
447 } 427 }
448 428
449 @override 429 @override
450 NodeCallback visitYield(cps_ir.Yield node) { 430 NodeCallback visitYield(cps_ir.Yield node) {
451 return (Statement next) { 431 return (Statement next) {
452 return new Yield(getVariableUse(node.input), node.hasStar, next); 432 return new Yield(getVariableUse(node.input), node.hasStar, next);
453 }; 433 };
454 } 434 }
455 435
456 @override 436 @override
457 NodeCallback visitAwait(cps_ir.Await node) { 437 Expression visitAwait(cps_ir.Await node) {
458 Expression value = new Await(getVariableUse(node.input)); 438 return new Await(getVariableUse(node.input));
459 return makeCallExpression(node, value);
460 } 439 }
461 440
462
463 /************************** TAIL EXPRESSIONS **************************/ 441 /************************** TAIL EXPRESSIONS **************************/
464 // 442 //
465 // Visit methods for tail expressions must return a statement directly 443 // Visit methods for tail expressions must return a statement directly
466 // (not a function like interior and call expressions). 444 // (not a function like interior and call expressions).
467 445
468 Statement visitThrow(cps_ir.Throw node) { 446 Statement visitThrow(cps_ir.Throw node) {
469 Expression value = getVariableUse(node.value); 447 Expression value = getVariableUse(node.value);
470 return new Throw(value); 448 return new Throw(value);
471 } 449 }
472 450
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 --enclosingFunctions; 712 --enclosingFunctions;
735 } 713 }
736 714
737 @override 715 @override
738 visitInterpolatedNode(js.InterpolatedNode node) { 716 visitInterpolatedNode(js.InterpolatedNode node) {
739 if (enclosingFunctions > 0) { 717 if (enclosingFunctions > 0) {
740 found = true; 718 found = true;
741 } 719 }
742 } 720 }
743 } 721 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698