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..1f67a630ba842601a604bef032addfa712385a34 |
| --- /dev/null |
| +++ b/runtime/lib/byte_array.cc |
| @@ -0,0 +1,304 @@ |
| +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| +// 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/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); |
| +} |
| + |
| + |
| +static RawSmi* GetIndexArgument(NativeArguments* arguments) { |
| + const Instance& index_instance = Instance::CheckedHandle(arguments->At(1)); |
|
Ivan Posva
2012/01/25 23:49:57
GET_NATIVE_ARGUMENT(Smi, index, arguments->At(1));
cshapiro
2012/01/26 02:25:42
Removed entirely.
|
| + 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.raw(); |
| +} |
| + |
| + |
| +static void RangeCheck(const ByteArray& array, const Smi& index, |
| + intptr_t num_bytes) { |
| + if ((index.Value() < 0) || ((index.Value() + num_bytes) > array.Length())) { |
| + GrowableArray<const Object*> arguments; |
| + arguments.Add(&index); |
| + Exceptions::ThrowByType(Exceptions::kIndexOutOfRange, arguments); |
| + } |
| +} |
| + |
| + |
| +#define GETTER(ArrayT, ObjectT, ValueT) \ |
| + const Instance& array_instance = \ |
|
Ivan Posva
2012/01/25 23:49:57
A whole chunk here can be replaced with:
GET_NATIV
cshapiro
2012/01/26 02:25:42
Yes, that looks much better. Done.
|
| + Instance::CheckedHandle(arguments->At(0)); \ |
| + if (!array_instance.Is##ArrayT()) { \ |
| + GrowableArray<const Object*> args; \ |
| + args.Add(&array_instance); \ |
| + Exceptions::ThrowByType(Exceptions::kIllegalArgument, args); \ |
| + } \ |
| + ArrayT& array = ArrayT::Handle(); \ |
| + array ^= array_instance.raw(); \ |
| + const Smi& index = Smi::Handle(GetIndexArgument(arguments)); \ |
| + RangeCheck(array, index, sizeof(ValueT)); \ |
| + const Instance& value_instance = \ |
| + Instance::CheckedHandle(arguments->At(1)); \ |
| + if (!value_instance.Is##ObjectT()) { \ |
| + GrowableArray<const Object*> args; \ |
| + args.Add(&value_instance); \ |
| + Exceptions::ThrowByType(Exceptions::kIllegalArgument, args); \ |
| + } \ |
| + ObjectT& value = ObjectT::Handle(); \ |
| + value ^= value_instance.raw(); \ |
|
siva
2012/01/25 17:22:47
Why do you need the value_instance stuff in the GE
cshapiro
2012/01/25 23:48:49
How embarrassing. You are correct.
|
| + ValueT result = array.UnalignedAt<ValueT>(index.Value()); \ |
| + arguments->SetReturn(ObjectT::Handle(ObjectT::New(result))); |
| + |
| + |
| +#define SETTER(ArrayT, ObjectT, Getter, ValueT) \ |
| + const Instance& array_instance = \ |
|
Ivan Posva
2012/01/25 23:49:57
ditto + GET_NATIVE_ARGUMENT(ObjectT, value, argume
cshapiro
2012/01/26 02:25:42
Yup. Done.
|
| + Instance::CheckedHandle(arguments->At(0)); \ |
| + if (!array_instance.Is##ArrayT()) { \ |
| + GrowableArray<const Object*> args; \ |
| + args.Add(&array_instance); \ |
| + Exceptions::ThrowByType(Exceptions::kIllegalArgument, args); \ |
| + } \ |
| + ArrayT& array = ArrayT::Handle(); \ |
| + array ^= array_instance.raw(); \ |
| + const Smi& index = Smi::Handle(GetIndexArgument(arguments)); \ |
| + RangeCheck(array, index, sizeof(ValueT)); \ |
| + const Instance& value_instance = \ |
| + Instance::CheckedHandle(arguments->At(2)); \ |
| + if (!value_instance.Is##ObjectT()) { \ |
| + GrowableArray<const Object*> args; \ |
| + args.Add(&value_instance); \ |
| + Exceptions::ThrowByType(Exceptions::kIllegalArgument, args); \ |
| + } \ |
| + ObjectT& value = ObjectT::Handle(); \ |
| + value ^= value_instance.raw(); \ |
| + array.SetUnalignedAt<ValueT>(index.Value(), value.Getter()); |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_getInt8, 2) { |
| + GETTER(InternalByteArray, Smi, int8_t); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_setInt8, 3) { |
| + SETTER(InternalByteArray, Smi, Value, int8_t); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_getUint8, 2) { |
| + GETTER(InternalByteArray, Smi, uint8_t); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_setUint8, 3) { |
| + SETTER(InternalByteArray, Smi, Value, uint8_t); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_getInt16, 2) { |
| + GETTER(InternalByteArray, Smi, int16_t); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_setInt16, 3) { |
| + SETTER(InternalByteArray, Smi, Value, int16_t); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_getUint16, 2) { |
| + GETTER(InternalByteArray, Smi, uint16_t); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_setUint16, 3) { |
| + SETTER(InternalByteArray, Smi, Value, uint16_t); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_getInt32, 2) { |
| + GETTER(InternalByteArray, Integer, int32_t); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_setInt32, 3) { |
| + SETTER(InternalByteArray, Integer, AsInt64Value, int32_t); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_getUint32, 2) { |
| + GETTER(InternalByteArray, Integer, uint32_t); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_setUint32, 3) { |
| + SETTER(InternalByteArray, Integer, AsInt64Value, uint32_t); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_getInt64, 2) { |
| + GETTER(InternalByteArray, Integer, int64_t); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_setInt64, 3) { |
| + SETTER(InternalByteArray, Integer, AsInt64Value, 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) { |
| + GETTER(InternalByteArray, Double, float); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_setFloat32, 3) { |
| + SETTER(InternalByteArray, Double, value, float); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_getFloat64, 2) { |
| + GETTER(InternalByteArray, Double, double); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(InternalByteArray_setFloat64, 3) { |
| + SETTER(InternalByteArray, Double, value, double); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_getInt8, 2) { |
| + GETTER(ExternalByteArray, Smi, int8_t); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_setInt8, 3) { |
| + SETTER(ExternalByteArray, Smi, Value, int8_t); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_getUint8, 2) { |
| + GETTER(ExternalByteArray, Smi, uint8_t); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_setUint8, 3) { |
| + SETTER(ExternalByteArray, Smi, Value, uint8_t); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_getInt16, 2) { |
| + GETTER(ExternalByteArray, Smi, int16_t); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_setInt16, 3) { |
| + SETTER(ExternalByteArray, Smi, Value, int16_t); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_getUint16, 2) { |
| + GETTER(ExternalByteArray, Smi, uint16_t); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_setUint16, 3) { |
| + SETTER(ExternalByteArray, Smi, Value, uint16_t); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_getInt32, 2) { |
| + GETTER(ExternalByteArray, Integer, int32_t); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_setInt32, 3) { |
| + SETTER(ExternalByteArray, Integer, AsInt64Value, int32_t); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_getUint32, 2) { |
| + GETTER(ExternalByteArray, Integer, uint32_t); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_setUint32, 3) { |
| + SETTER(ExternalByteArray, Integer, AsInt64Value, uint32_t); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_getInt64, 2) { |
| + GETTER(ExternalByteArray, Integer, int64_t); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_setInt64, 3) { |
| + SETTER(ExternalByteArray, Integer, AsInt64Value, 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) { |
| + GETTER(ExternalByteArray, Double, float); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_setFloat32, 3) { |
| + SETTER(ExternalByteArray, Double, value, float); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_getFloat64, 2) { |
| + GETTER(ExternalByteArray, Double, double); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(ExternalByteArray_setFloat64, 3) { |
| + SETTER(ExternalByteArray, Double, value, double); |
| +} |
| + |
| +} // namespace dart |