3b86f823d0
GrowableArrayMarker was a class that implemented int and was used to
enable implementation of default List factory constructor in pure Dart:
factory List([int length = GROWABLE_ARRAY_MARKER]) {
return identical(length, GROWABLE_ARRAY_MARKER) ? new _GrowableList<E>(0)
: new _List<E>(length);
}
Its existence complicated all kinds of things in the VM and it is finally
time to remove it.
Instead we build List factory body directly in IL.
This CL also provides inlining rule for `new List(n)` case.
Change-Id: I870751658a4ac17fce649c9ac70395ff88a5436c
Reviewed-on: https://dart-review.googlesource.com/57262
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
90 lines
3.2 KiB
C++
90 lines
3.2 KiB
C++
// 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 "platform/assert.h"
|
|
#include "vm/bootstrap_natives.h"
|
|
#include "vm/exceptions.h"
|
|
#include "vm/native_entry.h"
|
|
#include "vm/object.h"
|
|
|
|
namespace dart {
|
|
|
|
DEFINE_NATIVE_ENTRY(List_new, 2) {
|
|
// This function is handled by flow-graph builder.
|
|
UNREACHABLE();
|
|
return Object::null();
|
|
}
|
|
|
|
DEFINE_NATIVE_ENTRY(List_allocate, 2) {
|
|
// Implemented in FlowGraphBuilder::VisitNativeBody.
|
|
UNREACHABLE();
|
|
return Object::null();
|
|
}
|
|
|
|
DEFINE_NATIVE_ENTRY(List_getIndexed, 2) {
|
|
const Array& array = Array::CheckedHandle(arguments->NativeArgAt(0));
|
|
GET_NON_NULL_NATIVE_ARGUMENT(Smi, index, arguments->NativeArgAt(1));
|
|
if ((index.Value() < 0) || (index.Value() >= array.Length())) {
|
|
Exceptions::ThrowRangeError("index", index, 0, array.Length() - 1);
|
|
}
|
|
return array.At(index.Value());
|
|
}
|
|
|
|
DEFINE_NATIVE_ENTRY(List_setIndexed, 3) {
|
|
const Array& array = Array::CheckedHandle(arguments->NativeArgAt(0));
|
|
GET_NON_NULL_NATIVE_ARGUMENT(Smi, index, arguments->NativeArgAt(1));
|
|
const Instance& value = Instance::CheckedHandle(arguments->NativeArgAt(2));
|
|
if ((index.Value() < 0) || (index.Value() >= array.Length())) {
|
|
Exceptions::ThrowRangeError("index", index, 0, array.Length() - 1);
|
|
}
|
|
array.SetAt(index.Value(), value);
|
|
return Object::null();
|
|
}
|
|
|
|
DEFINE_NATIVE_ENTRY(List_getLength, 1) {
|
|
const Array& array = Array::CheckedHandle(arguments->NativeArgAt(0));
|
|
return Smi::New(array.Length());
|
|
}
|
|
|
|
// ObjectArray src, int start, int count, bool needTypeArgument.
|
|
DEFINE_NATIVE_ENTRY(List_slice, 4) {
|
|
const Array& src = Array::CheckedHandle(arguments->NativeArgAt(0));
|
|
GET_NON_NULL_NATIVE_ARGUMENT(Smi, start, arguments->NativeArgAt(1));
|
|
GET_NON_NULL_NATIVE_ARGUMENT(Smi, count, arguments->NativeArgAt(2));
|
|
GET_NON_NULL_NATIVE_ARGUMENT(Bool, needs_type_arg, arguments->NativeArgAt(3));
|
|
intptr_t istart = start.Value();
|
|
if ((istart < 0) || (istart > src.Length())) {
|
|
Exceptions::ThrowRangeError("start", start, 0, src.Length());
|
|
}
|
|
intptr_t icount = count.Value();
|
|
// Zero count should be handled outside already.
|
|
if ((icount <= 0) || (icount > src.Length())) {
|
|
Exceptions::ThrowRangeError("count", count,
|
|
0, // This is the limit the user sees.
|
|
src.Length() - istart);
|
|
}
|
|
|
|
return src.Slice(istart, icount, needs_type_arg.value());
|
|
}
|
|
|
|
// Private factory, expects correct arguments.
|
|
DEFINE_NATIVE_ENTRY(ImmutableList_from, 4) {
|
|
// Ignore first argument of a thsi factory (type argument).
|
|
const Array& from_array = Array::CheckedHandle(arguments->NativeArgAt(1));
|
|
const Smi& smi_offset = Smi::CheckedHandle(arguments->NativeArgAt(2));
|
|
const Smi& smi_length = Smi::CheckedHandle(arguments->NativeArgAt(3));
|
|
const intptr_t length = smi_length.Value();
|
|
const intptr_t offset = smi_offset.Value();
|
|
const Array& result = Array::Handle(Array::New(length));
|
|
Object& temp = Object::Handle();
|
|
for (intptr_t i = 0; i < length; i++) {
|
|
temp = from_array.At(i + offset);
|
|
result.SetAt(i, temp);
|
|
}
|
|
result.MakeImmutable();
|
|
return result.raw();
|
|
}
|
|
|
|
} // namespace dart
|