HInstruction* HGraphBuilder::BuildExternalArrayElementAccess(
    HValue* external_elements,
    HValue* checked_key,
    HValue* val,
    HValue* dependency,
    ElementsKind elements_kind,
    bool is_store) {
  if (is_store) {
    ASSERT(val != NULL);
    switch (elements_kind) {
      case EXTERNAL_PIXEL_ELEMENTS: {
        val = AddInstruction(new(zone()) HClampToUint8(val));
        break;
      }
      case EXTERNAL_BYTE_ELEMENTS:
      case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
      case EXTERNAL_SHORT_ELEMENTS:
      case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
      case EXTERNAL_INT_ELEMENTS:
      case EXTERNAL_UNSIGNED_INT_ELEMENTS: {
        if (!val->representation().IsInteger32()) {
          val = AddInstruction(new(zone()) HChange(
              val,
              Representation::Integer32(),
              true,  // Truncate to int32.
              false));  // Don't deoptimize undefined (irrelevant here).
        }
        break;
      }
      case EXTERNAL_FLOAT_ELEMENTS:
      case EXTERNAL_DOUBLE_ELEMENTS:
        break;
      case FAST_SMI_ELEMENTS:
      case FAST_ELEMENTS:
      case FAST_DOUBLE_ELEMENTS:
      case FAST_HOLEY_SMI_ELEMENTS:
      case FAST_HOLEY_ELEMENTS:
      case FAST_HOLEY_DOUBLE_ELEMENTS:
      case DICTIONARY_ELEMENTS:
      case NON_STRICT_ARGUMENTS_ELEMENTS:
        UNREACHABLE();
        break;
    }
    return new(zone()) HStoreKeyedSpecializedArrayElement(
        external_elements, checked_key, val, elements_kind);
  } else {
    ASSERT(val == NULL);
    HLoadKeyedSpecializedArrayElement* load =
       new(zone()) HLoadKeyedSpecializedArrayElement(
          external_elements, checked_key, dependency, elements_kind);
    if (FLAG_opt_safe_uint32_operations &&
        elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) {
      graph()->RecordUint32Instruction(load);
    }
    return load;
  }
}
HInstruction* HGraphBuilder::BuildExternalArrayElementAccess(
    HValue* external_elements,
    HValue* checked_key,
    HValue* val,
    HValue* dependency,
    ElementsKind elements_kind,
    bool is_store) {
  if (is_store) {
    ASSERT(val != NULL);
    switch (elements_kind) {
      case EXTERNAL_PIXEL_ELEMENTS: {
        val = AddInstruction(new(zone()) HClampToUint8(val));
        break;
      }
      case EXTERNAL_BYTE_ELEMENTS:
      case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
      case EXTERNAL_SHORT_ELEMENTS:
      case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
      case EXTERNAL_INT_ELEMENTS:
      case EXTERNAL_UNSIGNED_INT_ELEMENTS: {
        if (!val->representation().IsInteger32()) {
          val = AddInstruction(new(zone()) HChange(
              val,
              Representation::Integer32(),
              true,   
              false));   
        }
        break;
      }
      case EXTERNAL_FLOAT_ELEMENTS:
      case EXTERNAL_DOUBLE_ELEMENTS:
        break;
      case FAST_SMI_ELEMENTS:
      case FAST_ELEMENTS:
      case FAST_DOUBLE_ELEMENTS:
      case FAST_HOLEY_SMI_ELEMENTS:
      case FAST_HOLEY_ELEMENTS:
      case FAST_HOLEY_DOUBLE_ELEMENTS:
      case DICTIONARY_ELEMENTS:
      case NON_STRICT_ARGUMENTS_ELEMENTS:
        UNREACHABLE();
        break;
    }
    return new(zone()) HStoreKeyedSpecializedArrayElement(
        external_elements, checked_key, val, elements_kind);
  } else {
    ASSERT(val == NULL);
    HLoadKeyedSpecializedArrayElement* load =
       new(zone()) HLoadKeyedSpecializedArrayElement(
          external_elements, checked_key, dependency, elements_kind);
    if (FLAG_opt_safe_uint32_operations &&
        elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) {
      graph()->RecordUint32Instruction(load);
    }
    return load;
  }
}