| Index: src/compiler/js-builtin-reducer.cc
|
| diff --git a/src/compiler/js-builtin-reducer.cc b/src/compiler/js-builtin-reducer.cc
|
| index a9af93c80ce9cb6e661d72ab5ff189ca6aa49884..e3bafadaef0ef1304680fa9553d4617000e3a57c 100644
|
| --- a/src/compiler/js-builtin-reducer.cc
|
| +++ b/src/compiler/js-builtin-reducer.cc
|
| @@ -725,6 +725,104 @@ Reduction JSBuiltinReducer::ReduceArrayIteratorNext(Node* node) {
|
| return NoChange();
|
| }
|
|
|
| +// ES6 section 22.1.2.2 Array.isArray ( arg )
|
| +Reduction JSBuiltinReducer::ReduceArrayIsArray(Node* node) {
|
| + // We certainly know that undefined is not an array.
|
| + if (node->op()->ValueInputCount() < 3) {
|
| + Node* value = jsgraph()->FalseConstant();
|
| + ReplaceWithValue(node, value);
|
| + return Replace(value);
|
| + }
|
| + Node* value = NodeProperties::GetValueInput(node, 2);
|
| + Node* context = NodeProperties::GetContextInput(node);
|
| + Node* frame_state = NodeProperties::GetFrameStateInput(node);
|
| + Node* effect = NodeProperties::GetEffectInput(node);
|
| + Node* control = NodeProperties::GetControlInput(node);
|
| +
|
| + int count = 0;
|
| + Node* values[5];
|
| + Node* effects[5];
|
| + Node* controls[4];
|
| +
|
| + // Check if the {value} is a Smi.
|
| + Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), value);
|
| + control =
|
| + graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
|
| +
|
| + // The {value} is a Smi.
|
| + controls[count] = graph()->NewNode(common()->IfTrue(), control);
|
| + effects[count] = effect;
|
| + values[count] = jsgraph()->FalseConstant();
|
| + count++;
|
| +
|
| + control = graph()->NewNode(common()->IfFalse(), control);
|
| +
|
| + // Load the {value}s instance type.
|
| + Node* value_map = effect = graph()->NewNode(
|
| + simplified()->LoadField(AccessBuilder::ForMap()), value, effect, control);
|
| + Node* value_instance_type = effect = graph()->NewNode(
|
| + simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map,
|
| + effect, control);
|
| +
|
| + // Check if the {value} is a JSArray.
|
| + check = graph()->NewNode(simplified()->NumberEqual(), value_instance_type,
|
| + jsgraph()->Constant(JS_ARRAY_TYPE));
|
| + control = graph()->NewNode(common()->Branch(), check, control);
|
| +
|
| + // The {value} is a JSArray.
|
| + controls[count] = graph()->NewNode(common()->IfTrue(), control);
|
| + effects[count] = effect;
|
| + values[count] = jsgraph()->TrueConstant();
|
| + count++;
|
| +
|
| + control = graph()->NewNode(common()->IfFalse(), control);
|
| +
|
| + // Check if the {value} is a JSProxy.
|
| + check = graph()->NewNode(simplified()->NumberEqual(), value_instance_type,
|
| + jsgraph()->Constant(JS_PROXY_TYPE));
|
| + control =
|
| + graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
|
| +
|
| + // The {value} is neither a JSArray nor a JSProxy.
|
| + controls[count] = graph()->NewNode(common()->IfFalse(), control);
|
| + effects[count] = effect;
|
| + values[count] = jsgraph()->FalseConstant();
|
| + count++;
|
| +
|
| + control = graph()->NewNode(common()->IfTrue(), control);
|
| +
|
| + // Let the %ArrayIsArray runtime function deal with the JSProxy {value}.
|
| + value = effect =
|
| + graph()->NewNode(javascript()->CallRuntime(Runtime::kArrayIsArray), value,
|
| + context, frame_state, effect, control);
|
| + NodeProperties::SetType(value, Type::Boolean());
|
| + control = graph()->NewNode(common()->IfSuccess(), value);
|
| +
|
| + // Rewire any IfException edges on {node} to {value}.
|
| + for (Edge edge : node->use_edges()) {
|
| + Node* const user = edge.from();
|
| + if (user->opcode() == IrOpcode::kIfException) {
|
| + edge.UpdateTo(value);
|
| + Revisit(user);
|
| + }
|
| + }
|
| +
|
| + // The {value} is neither a JSArray nor a JSProxy.
|
| + controls[count] = control;
|
| + effects[count] = effect;
|
| + values[count] = value;
|
| + count++;
|
| +
|
| + control = graph()->NewNode(common()->Merge(count), count, controls);
|
| + effects[count] = control;
|
| + values[count] = control;
|
| + effect = graph()->NewNode(common()->EffectPhi(count), count + 1, effects);
|
| + value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, count),
|
| + count + 1, values);
|
| + ReplaceWithValue(node, value, effect, control);
|
| + return Replace(value);
|
| +}
|
| +
|
| // ES6 section 22.1.3.17 Array.prototype.pop ( )
|
| Reduction JSBuiltinReducer::ReduceArrayPop(Node* node) {
|
| Handle<Map> receiver_map;
|
| @@ -1969,6 +2067,8 @@ Reduction JSBuiltinReducer::Reduce(Node* node) {
|
| return ReduceArrayIterator(node, IterationKind::kValues);
|
| case kArrayIteratorNext:
|
| return ReduceArrayIteratorNext(node);
|
| + case kArrayIsArray:
|
| + return ReduceArrayIsArray(node);
|
| case kArrayPop:
|
| return ReduceArrayPop(node);
|
| case kArrayPush:
|
|
|