88878148ac
Review URL: http://codereview.chromium.org//8678025 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@1817 260f80e4-7a28-3924-810f-c04153c831b5
235 lines
5.6 KiB
C++
235 lines
5.6 KiB
C++
// Copyright (c) 2011, 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/assembler.h"
|
|
#include "vm/assert.h"
|
|
#include "vm/bigint_operations.h"
|
|
#include "vm/exceptions.h"
|
|
#include "vm/native_entry.h"
|
|
#include "vm/object.h"
|
|
|
|
namespace dart {
|
|
|
|
DEFINE_NATIVE_ENTRY(ByteBuffer_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);
|
|
}
|
|
uint8_t* data = new uint8_t[length.Value()];
|
|
memset(data, 0, length.Value());
|
|
const ByteBuffer& new_array =
|
|
ByteBuffer::Handle(ByteBuffer::New(data, length.Value()));
|
|
arguments->SetReturn(new_array);
|
|
}
|
|
|
|
|
|
DEFINE_NATIVE_ENTRY(ByteBuffer_getLength, 1) {
|
|
const ByteBuffer& array = ByteBuffer::CheckedHandle(arguments->At(0));
|
|
const Smi& length = Smi::Handle(Smi::New(array.Length()));
|
|
arguments->SetReturn(length);
|
|
}
|
|
|
|
|
|
template<typename ValueType, typename ObjectType>
|
|
static void GetIndexed(NativeArguments* arguments) {
|
|
const ByteBuffer& buffer = ByteBuffer::CheckedHandle(arguments->At(0));
|
|
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();
|
|
if (buffer.IsNull() || index.IsNull()) {
|
|
// TODO(asiva): Need to handle error cases.
|
|
UNIMPLEMENTED();
|
|
return;
|
|
}
|
|
intptr_t num_bytes = sizeof(ValueType);
|
|
if ((index.Value() < 0) || ((index.Value() + num_bytes) > buffer.Length())) {
|
|
GrowableArray<const Object*> arguments;
|
|
arguments.Add(&index);
|
|
Exceptions::ThrowByType(Exceptions::kIndexOutOfRange, arguments);
|
|
}
|
|
arguments->SetReturn(
|
|
ObjectType::Handle(
|
|
ObjectType::New(buffer.UnalignedAt<ValueType>(index.Value()))));
|
|
}
|
|
|
|
|
|
template<typename T> static bool HasType(const Object& obj);
|
|
|
|
|
|
template<>
|
|
bool HasType<Smi>(const Object& obj) {
|
|
return obj.IsSmi();
|
|
}
|
|
|
|
|
|
template<>
|
|
bool HasType<Integer>(const Object& obj) {
|
|
return obj.IsInteger();
|
|
}
|
|
|
|
|
|
template<>
|
|
bool HasType<Double>(const Object& obj) {
|
|
return obj.IsDouble();
|
|
}
|
|
|
|
|
|
static intptr_t Value(const Smi& obj) {
|
|
return obj.Value();
|
|
}
|
|
|
|
|
|
static int64_t Value(const Integer& obj) {
|
|
return obj.AsInt64Value();
|
|
}
|
|
|
|
|
|
static double Value(const Double& obj) {
|
|
return obj.value();
|
|
}
|
|
|
|
|
|
template<typename ValueType, typename ObjectType>
|
|
static void SetIndexed(const NativeArguments* arguments) {
|
|
const ByteBuffer& buffer = ByteBuffer::CheckedHandle(arguments->At(0));
|
|
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();
|
|
const Instance& value_instance = Instance::CheckedHandle(arguments->At(2));
|
|
if (buffer.IsNull() || index.IsNull()) {
|
|
// TODO(asiva): Need to handle error cases.
|
|
UNIMPLEMENTED();
|
|
return;
|
|
}
|
|
if (index.Value() >= buffer.Length()) {
|
|
GrowableArray<const Object*> arguments;
|
|
arguments.Add(&index);
|
|
Exceptions::ThrowByType(Exceptions::kIndexOutOfRange, arguments);
|
|
}
|
|
if (!HasType<ObjectType>(value_instance)) {
|
|
GrowableArray<const Object*> args;
|
|
args.Add(&value_instance);
|
|
Exceptions::ThrowByType(Exceptions::kIllegalArgument, args);
|
|
}
|
|
ObjectType& value = ObjectType::Handle();
|
|
value ^= value_instance.raw();
|
|
buffer.SetUnalignedAt<ValueType>(index.Value(), Value(value));
|
|
}
|
|
|
|
|
|
DEFINE_NATIVE_ENTRY(ByteBuffer_getInt8, 2) {
|
|
GetIndexed<int8_t, Smi>(arguments);
|
|
}
|
|
|
|
|
|
DEFINE_NATIVE_ENTRY(ByteBuffer_setInt8, 3) {
|
|
SetIndexed<int8_t, Smi>(arguments);
|
|
}
|
|
|
|
|
|
DEFINE_NATIVE_ENTRY(ByteBuffer_getUint8, 2) {
|
|
GetIndexed<uint8_t, Smi>(arguments);
|
|
}
|
|
|
|
|
|
DEFINE_NATIVE_ENTRY(ByteBuffer_setUint8, 3) {
|
|
SetIndexed<uint8_t, Smi>(arguments);
|
|
}
|
|
|
|
|
|
DEFINE_NATIVE_ENTRY(ByteBuffer_getInt16, 2) {
|
|
GetIndexed<int16_t, Smi>(arguments);
|
|
}
|
|
|
|
|
|
DEFINE_NATIVE_ENTRY(ByteBuffer_setInt16, 3) {
|
|
SetIndexed<int16_t, Smi>(arguments);
|
|
}
|
|
|
|
|
|
DEFINE_NATIVE_ENTRY(ByteBuffer_getUint16, 2) {
|
|
GetIndexed<uint16_t, Smi>(arguments);
|
|
}
|
|
|
|
|
|
DEFINE_NATIVE_ENTRY(ByteBuffer_setUint16, 3) {
|
|
SetIndexed<uint16_t, Smi>(arguments);
|
|
}
|
|
|
|
|
|
DEFINE_NATIVE_ENTRY(ByteBuffer_getInt32, 2) {
|
|
GetIndexed<int32_t, Integer>(arguments);
|
|
}
|
|
|
|
|
|
DEFINE_NATIVE_ENTRY(ByteBuffer_setInt32, 3) {
|
|
SetIndexed<int32_t, Integer>(arguments);
|
|
}
|
|
|
|
|
|
DEFINE_NATIVE_ENTRY(ByteBuffer_getUint32, 2) {
|
|
GetIndexed<uint32_t, Integer>(arguments);
|
|
}
|
|
|
|
|
|
DEFINE_NATIVE_ENTRY(ByteBuffer_setUint32, 3) {
|
|
SetIndexed<uint32_t, Integer>(arguments);
|
|
}
|
|
|
|
|
|
DEFINE_NATIVE_ENTRY(ByteBuffer_getInt64, 2) {
|
|
GetIndexed<int64_t, Integer>(arguments);
|
|
}
|
|
|
|
|
|
DEFINE_NATIVE_ENTRY(ByteBuffer_setInt64, 3) {
|
|
SetIndexed<int64_t, Integer>(arguments);
|
|
}
|
|
|
|
|
|
DEFINE_NATIVE_ENTRY(ByteBuffer_getUint64, 2) {
|
|
UNIMPLEMENTED(); // TODO(cshapiro): need getter implementation.
|
|
}
|
|
|
|
|
|
DEFINE_NATIVE_ENTRY(ByteBuffer_setUint64, 3) {
|
|
UNIMPLEMENTED(); // TODO(cshapiro): need setter implementation.
|
|
}
|
|
|
|
|
|
DEFINE_NATIVE_ENTRY(ByteBuffer_getFloat32, 2) {
|
|
GetIndexed<float, Double>(arguments);
|
|
}
|
|
|
|
|
|
DEFINE_NATIVE_ENTRY(ByteBuffer_setFloat32, 3) {
|
|
SetIndexed<float, Double>(arguments);
|
|
}
|
|
|
|
|
|
DEFINE_NATIVE_ENTRY(ByteBuffer_getFloat64, 2) {
|
|
GetIndexed<double, Double>(arguments);
|
|
}
|
|
|
|
|
|
DEFINE_NATIVE_ENTRY(ByteBuffer_setFloat64, 3) {
|
|
SetIndexed<double, Double>(arguments);
|
|
}
|
|
|
|
} // namespace dart
|