Chromium Code Reviews| Index: runtime/lib/byte_array.cc |
| diff --git a/runtime/lib/byte_array.cc b/runtime/lib/byte_array.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..a8d537aadd98a637224bf23525100f3a38d1d003 |
| --- /dev/null |
| +++ b/runtime/lib/byte_array.cc |
| @@ -0,0 +1,340 @@ |
| +// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
|
siva
2012/01/20 22:51:04
2012 here and other files.
|
| +// for details. All rights reserved. Use of this source code is governed by a |
| +// BSD-style license that can be found in the LICENSE file. |
| + |
| +#include "vm/bootstrap_natives.h" |
| + |
| +#include "vm/assembler.h" |
|
siva
2012/01/20 22:51:04
Why does assembler.h have to included here?
cshapiro
2012/01/24 02:14:23
True. In fact, both assembler.h and bigint_operat
|
| +#include "vm/bigint_operations.h" |
| +#include "vm/exceptions.h" |
| +#include "vm/native_entry.h" |
| +#include "vm/object.h" |
| + |
| +namespace dart { |
| + |
| +DEFINE_NATIVE_ENTRY(ByteArray_getLength, 1) { |
| + const ByteArray& byte_array = ByteArray::CheckedHandle(arguments->At(0)); |
| + const Smi& length = Smi::Handle(Smi::New(byte_array.Length())); |
| + arguments->SetReturn(length); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_allocate, 1) { |
| + GET_NATIVE_ARGUMENT(Smi, length, arguments->At(0)); |
| + if (length.Value() < 0) { |
| + GrowableArray<const Object*> args; |
| + args.Add(&length); |
| + Exceptions::ThrowByType(Exceptions::kIllegalArgument, args); |
| + } |
| + const InternalByteArray& new_array = |
| + InternalByteArray::Handle(InternalByteArray::New(length.Value())); |
| + arguments->SetReturn(new_array); |
| +} |
| + |
| + |
| +template<typename T> |
| +static const T& GetArray(NativeArguments* arguments) { |
| + const T& byte_array = T::CheckedHandle(arguments->At(0)); |
| + if (!byte_array.IsByteArray()) { |
|
siva
2012/01/20 22:51:04
Checked handle will assert out if it is not a byte
cshapiro
2012/01/24 02:14:23
Fixed, the hard way.
|
| + GrowableArray<const Object*> args; |
| + args.Add(&byte_array); |
| + Exceptions::ThrowByType(Exceptions::kIllegalArgument, args); |
| + } |
| + return byte_array; |
| +} |
| + |
| + |
| +static Smi& GetIndex(NativeArguments* arguments) { |
|
siva
2012/01/20 22:51:04
Our normal style has been to return raw objects fr
|
| + const Instance& index_instance = Instance::CheckedHandle(arguments->At(1)); |
| + if (!index_instance.IsSmi()) { |
| + GrowableArray<const Object*> args; |
| + args.Add(&index_instance); |
| + Exceptions::ThrowByType(Exceptions::kIllegalArgument, args); |
| + } |
| + Smi& index = Smi::Handle(); |
| + index ^= index_instance.raw(); |
| + return index; |
|
siva
2012/01/20 22:51:04
just return reinterpret_cast<RawSmi*>(index_instan
|
| +} |
| + |
| + |
| +template<typename T> |
| +static void RangeCheck(const ByteArray& array, const Smi& index) { |
| + intptr_t num_bytes = sizeof(T); |
| + if ((index.Value() < 0) || ((index.Value() + num_bytes) > array.Length())) { |
| + GrowableArray<const Object*> arguments; |
| + arguments.Add(&index); |
| + Exceptions::ThrowByType(Exceptions::kIndexOutOfRange, arguments); |
| + } |
| +} |
| + |
| + |
| +template<typename T> |
| +static T GetSmiValue(NativeArguments* arguments) { |
| + const Instance& value_instance = Instance::CheckedHandle(arguments->At(2)); |
| + if (value_instance.IsSmi()) { |
|
siva
2012/01/20 22:51:04
shouldn't this be
if (!value_instance.IsSmi()) {
|
| + GrowableArray<const Object*> args; |
| + args.Add(&value_instance); |
| + Exceptions::ThrowByType(Exceptions::kIllegalArgument, args); |
| + } |
| + Smi& value = Smi::Handle(); |
| + value ^= value_instance.raw(); |
| + return value.Value(); |
| +} |
| + |
| + |
| +template<typename T> |
| +static T GetIntegerValue(NativeArguments* arguments) { |
| + const Instance& value_instance = Instance::CheckedHandle(arguments->At(2)); |
| + if (value_instance.IsInteger()) { |
|
siva
2012/01/20 22:51:04
if (!value_instance.IsInteger()) {
...
...
}
|
| + GrowableArray<const Object*> args; |
| + args.Add(&value_instance); |
| + Exceptions::ThrowByType(Exceptions::kIllegalArgument, args); |
| + } |
| + Integer& value = Integer::Handle(); |
| + value ^= value_instance.raw(); |
| + return value.AsInt64Value(); |
| +} |
| + |
| + |
| +template<typename T> |
| +static T GetDoubleValue(NativeArguments* arguments) { |
| + const Instance& value_instance = Instance::CheckedHandle(arguments->At(2)); |
| + if (value_instance.IsDouble()) { |
|
siva
2012/01/20 22:51:04
if (!value_instance.IsDouble()) {
...
...
}
|
| + GrowableArray<const Object*> args; |
| + args.Add(&value_instance); |
| + Exceptions::ThrowByType(Exceptions::kIllegalArgument, args); |
| + } |
| + Double& value = Double::Handle(); |
| + value ^= value_instance.raw(); |
| + return value.value(); |
| +} |
| + |
| + |
| +template<typename ArrayType, typename PrimitiveType, typename ObjectType> |
| +static void GetIndexed(NativeArguments* arguments) { |
| + const InternalByteArray& array = GetArray<InternalByteArray>(arguments); |
|
siva
2012/01/20 22:51:04
const ArrayType& array = GetArray<ArrayType>(argum
|
| + Smi& index = GetIndex(arguments); |
| + RangeCheck<PrimitiveType>(array, index); |
| + PrimitiveType result = array.UnalignedAt<PrimitiveType>(index.Value()); |
| + arguments->SetReturn(ObjectType::Handle(ObjectType::New(result))); |
| +} |
| + |
| + |
| +template<typename ArrayType, typename PrimitiveType, typename Getter> |
| +static void SetIndexed(NativeArguments* arguments, Getter getter) { |
| + const InternalByteArray& array = GetArray<InternalByteArray>(arguments); |
|
siva
2012/01/20 22:51:04
Ditto here?
|
| + Smi& index = GetIndex(arguments); |
| + RangeCheck<PrimitiveType>(array, index); |
| + PrimitiveType value = getter(arguments); |
| + array.SetUnalignedAt<PrimitiveType>(index.Value(), value); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_getInt8, 2) { |
| + const InternalByteArray& array = GetArray<InternalByteArray>(arguments); |
| + Smi& index = GetIndex(arguments); |
| + RangeCheck<int8_t>(array, index); |
| + int8_t result = array.UnalignedAt<int8_t>(index.Value()); |
| + arguments->SetReturn(Smi::Handle(Smi::New(result))); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_setInt8, 3) { |
| + const InternalByteArray& array = GetArray<InternalByteArray>(arguments); |
| + const Smi& index = GetIndex(arguments); |
| + RangeCheck<int8_t>(array, index); |
| + int8_t value = GetSmiValue<int8_t>(arguments); |
| + array.SetUnalignedAt<int8_t>(index.Value(), value); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_getUint8, 2) { |
| + GetIndexed<InternalByteArray, uint8_t, Smi>(arguments); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_setUint8, 3) { |
| + SetIndexed<InternalByteArray, uint8_t>(arguments, GetSmiValue<uint8_t>); |
|
siva
2012/01/20 22:51:04
The template instantiation here takes only two typ
|
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_getInt16, 2) { |
| + GetIndexed<InternalByteArray, int16_t, Smi>(arguments); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_setInt16, 3) { |
| + SetIndexed<InternalByteArray, int16_t>(arguments, GetSmiValue<int16_t>); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_getUint16, 2) { |
| + GetIndexed<InternalByteArray, uint16_t, Smi>(arguments); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_setUint16, 3) { |
| + SetIndexed<InternalByteArray, uint16_t>(arguments, GetSmiValue<uint16_t>); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_getInt32, 2) { |
| + GetIndexed<InternalByteArray, int32_t, Integer>(arguments); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_setInt32, 3) { |
| + SetIndexed<InternalByteArray, int32_t>(arguments, GetSmiValue<int32_t>); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_getUint32, 2) { |
| + GetIndexed<InternalByteArray, uint32_t, Integer>(arguments); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_setUint32, 3) { |
| + SetIndexed<InternalByteArray, uint32_t>(arguments, GetIntegerValue<uint32_t>); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_getInt64, 2) { |
| + GetIndexed<InternalByteArray, int64_t, Integer>(arguments); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_setInt64, 3) { |
| + SetIndexed<InternalByteArray, int64_t>(arguments, GetIntegerValue<int64_t>); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_getUint64, 2) { |
| + UNIMPLEMENTED(); // TODO(cshapiro): need getter implementation. |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_setUint64, 3) { |
| + UNIMPLEMENTED(); // TODO(cshapiro): need setter implementation. |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_getFloat32, 2) { |
| + GetIndexed<InternalByteArray, float, Double>(arguments); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_setFloat32, 3) { |
| + SetIndexed<InternalByteArray, float>(arguments, GetDoubleValue<float>); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_getFloat64, 2) { |
| + GetIndexed<InternalByteArray, double, Double>(arguments); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_setFloat64, 3) { |
| + SetIndexed<InternalByteArray, double>(arguments, GetDoubleValue<double>); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_getInt8, 2) { |
| + GetIndexed<ExternalByteArray, int8_t, Smi>(arguments); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_setInt8, 3) { |
| + SetIndexed<ExternalByteArray, int8_t>(arguments, GetSmiValue<int8_t>); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_getUint8, 2) { |
| + GetIndexed<ExternalByteArray, uint8_t, Smi>(arguments); |
|
siva
2012/01/20 22:51:04
I don't understand how these worked as GetIndexed
|
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_setUint8, 3) { |
| + SetIndexed<ExternalByteArray, uint8_t>(arguments, GetSmiValue<uint8_t>); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_getInt16, 2) { |
| + GetIndexed<ExternalByteArray, int16_t, Smi>(arguments); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_setInt16, 3) { |
| + SetIndexed<ExternalByteArray, int16_t>(arguments, GetSmiValue<int16_t>); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_getUint16, 2) { |
| + GetIndexed<ExternalByteArray, uint16_t, Smi>(arguments); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_setUint16, 3) { |
| + SetIndexed<ExternalByteArray, uint16_t>(arguments, GetSmiValue<uint16_t>); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_getInt32, 2) { |
| + GetIndexed<ExternalByteArray, int32_t, Integer>(arguments); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_setInt32, 3) { |
| + SetIndexed<ExternalByteArray, int32_t>(arguments, GetIntegerValue<int32_t>); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_getUint32, 2) { |
| + GetIndexed<ExternalByteArray, uint32_t, Integer>(arguments); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_setUint32, 3) { |
| + SetIndexed<ExternalByteArray, uint32_t>(arguments, GetIntegerValue<uint32_t>); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_getInt64, 2) { |
| + GetIndexed<ExternalByteArray, int64_t, Integer>(arguments); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_setInt64, 3) { |
| + SetIndexed<ExternalByteArray, int64_t>(arguments, GetIntegerValue<int64_t>); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_getUint64, 2) { |
| + UNIMPLEMENTED(); // TODO(cshapiro): need getter implementation. |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_setUint64, 3) { |
| + UNIMPLEMENTED(); // TODO(cshapiro): need setter implementation. |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_getFloat32, 2) { |
| + GetIndexed<ExternalByteArray, float, Double>(arguments); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_setFloat32, 3) { |
| + SetIndexed<ExternalByteArray, float>(arguments, GetDoubleValue<float>); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_getFloat64, 2) { |
| + GetIndexed<ExternalByteArray, double, Double>(arguments); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_setFloat64, 3) { |
| + SetIndexed<ExternalByteArray, double>(arguments, GetDoubleValue<double>); |
| +} |
| + |
| +} // namespace dart |