| Index: runtime/vm/flow_graph_builder.cc
|
| ===================================================================
|
| --- runtime/vm/flow_graph_builder.cc (revision 26025)
|
| +++ runtime/vm/flow_graph_builder.cc (working copy)
|
| @@ -946,6 +946,16 @@
|
| }
|
|
|
|
|
| +
|
| +static const String& BinaryOpAndMaskName(BinaryOpNode* node) {
|
| + if (node->kind() == Token::kSHL) {
|
| + return PrivateCoreLibName(Symbols::_leftShiftWithMask32());
|
| + }
|
| + UNIMPLEMENTED();
|
| + return String::ZoneHandle();
|
| +}
|
| +
|
| +
|
| // <Expression> :: BinaryOp { kind: Token::Kind
|
| // left: <Expression>
|
| // right: <Expression> }
|
| @@ -953,6 +963,7 @@
|
| // Operators "&&" and "||" cannot be overloaded therefore do not call
|
| // operator.
|
| if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) {
|
| + ASSERT(!node->has_mask32());
|
| // See ValueGraphVisitor::VisitBinaryOpNode.
|
| TestGraphVisitor for_left(owner(),
|
| temp_index(),
|
| @@ -978,18 +989,40 @@
|
| Append(for_right_value);
|
| PushArgumentInstr* push_right = PushArgument(for_right_value.value());
|
|
|
| + PushArgumentInstr* push_mask = NULL;
|
| + if (node->has_mask32()) {
|
| + Value* mask_value = Bind(new ConstantInstr(
|
| + Integer::ZoneHandle(Integer::New(node->mask32(), Heap::kOld))));
|
| + push_mask = PushArgument(mask_value);
|
| + }
|
| +
|
| + InstanceCallInstr* call = NULL;
|
| ZoneGrowableArray<PushArgumentInstr*>* arguments =
|
| - new ZoneGrowableArray<PushArgumentInstr*>(2);
|
| + new ZoneGrowableArray<PushArgumentInstr*>(node->has_mask32() ? 3 : 2);
|
| arguments->Add(push_left);
|
| arguments->Add(push_right);
|
| - const String& name = String::ZoneHandle(Symbols::New(node->Name()));
|
| - InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(),
|
| - name,
|
| - node->kind(),
|
| - arguments,
|
| - Object::null_array(),
|
| - 2,
|
| - owner()->ic_data_array());
|
| + if (node->has_mask32()) {
|
| + // Call to special method 'BinaryOpAndMaskName(node)'.
|
| + arguments->Add(push_mask);
|
| + call = new InstanceCallInstr(node->token_pos(),
|
| + BinaryOpAndMaskName(node),
|
| + Token::kILLEGAL,
|
| + arguments,
|
| + Object::null_array(),
|
| + 2, // Collect data for both arguments.
|
| + owner()->ic_data_array());
|
| +
|
| + } else {
|
| + // Regular code.
|
| + const String& name = String::ZoneHandle(Symbols::New(node->Name()));
|
| + call = new InstanceCallInstr(node->token_pos(),
|
| + name,
|
| + node->kind(),
|
| + arguments,
|
| + Object::null_array(),
|
| + 2, // Collect data for both arguments.
|
| + owner()->ic_data_array());
|
| + }
|
| ReturnDefinition(call);
|
| }
|
|
|
| @@ -999,6 +1032,7 @@
|
| // Operators "&&" and "||" cannot be overloaded therefore do not call
|
| // operator.
|
| if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) {
|
| + ASSERT(!node->has_mask32());
|
| // Implement short-circuit logic: do not evaluate right if evaluation
|
| // of left is sufficient.
|
| // AND: left ? right === true : false;
|
|
|