Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/dart_entry.h" | 5 #include "vm/dart_entry.h" |
| 6 | 6 |
| 7 #include "vm/code_generator.h" | 7 #include "vm/code_generator.h" |
| 8 #include "vm/compiler.h" | 8 #include "vm/compiler.h" |
| 9 #include "vm/object_store.h" | 9 #include "vm/object_store.h" |
| 10 #include "vm/resolver.h" | 10 #include "vm/resolver.h" |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 37 args.Add(arguments[i - 1]); | 37 args.Add(arguments[i - 1]); |
| 38 } | 38 } |
| 39 // Now Call the invoke stub which will invoke the dart function. | 39 // Now Call the invoke stub which will invoke the dart function. |
| 40 invokestub entrypoint = reinterpret_cast<invokestub>( | 40 invokestub entrypoint = reinterpret_cast<invokestub>( |
| 41 StubCode::InvokeDartCodeEntryPoint()); | 41 StubCode::InvokeDartCodeEntryPoint()); |
| 42 const Context& context = | 42 const Context& context = |
| 43 Context::ZoneHandle(Isolate::Current()->object_store()->empty_context()); | 43 Context::ZoneHandle(Isolate::Current()->object_store()->empty_context()); |
| 44 ASSERT(context.isolate() == Isolate::Current()); | 44 ASSERT(context.isolate() == Isolate::Current()); |
| 45 const Code& code = Code::Handle(function.CurrentCode()); | 45 const Code& code = Code::Handle(function.CurrentCode()); |
| 46 ASSERT(!code.IsNull()); | 46 ASSERT(!code.IsNull()); |
| 47 return entrypoint( | 47 const Array& arg_descriptor = |
| 48 code.EntryPoint(), | 48 Array::Handle(ArgumentsDescriptor::New(num_arguments, |
| 49 ArgumentsDescriptor(num_arguments, optional_arguments_names), | 49 optional_arguments_names)); |
| 50 args.data(), | 50 return entrypoint(code.EntryPoint(), arg_descriptor, args.data(), context); |
| 51 context); | |
| 52 } | 51 } |
| 53 | 52 |
| 54 | 53 |
| 55 RawObject* DartEntry::InvokeStatic( | 54 RawObject* DartEntry::InvokeStatic( |
| 56 const Function& function, | 55 const Function& function, |
| 57 const GrowableArray<const Object*>& arguments, | 56 const GrowableArray<const Object*>& arguments, |
| 58 const Array& optional_arguments_names) { | 57 const Array& optional_arguments_names) { |
| 59 // Get the entrypoint corresponding to the function specified, this | 58 // Get the entrypoint corresponding to the function specified, this |
| 60 // will result in a compilation of the function if it is not already | 59 // will result in a compilation of the function if it is not already |
| 61 // compiled. | 60 // compiled. |
| 62 ASSERT(!function.IsNull()); | 61 ASSERT(!function.IsNull()); |
| 63 if (!function.HasCode()) { | 62 if (!function.HasCode()) { |
| 64 const Error& error = Error::Handle(Compiler::CompileFunction(function)); | 63 const Error& error = Error::Handle(Compiler::CompileFunction(function)); |
| 65 if (!error.IsNull()) { | 64 if (!error.IsNull()) { |
| 66 return error.raw(); | 65 return error.raw(); |
| 67 } | 66 } |
| 68 } | 67 } |
| 69 // Now Call the invoke stub which will invoke the dart function. | 68 // Now Call the invoke stub which will invoke the dart function. |
| 70 invokestub entrypoint = reinterpret_cast<invokestub>( | 69 invokestub entrypoint = reinterpret_cast<invokestub>( |
| 71 StubCode::InvokeDartCodeEntryPoint()); | 70 StubCode::InvokeDartCodeEntryPoint()); |
| 72 const Context& context = | 71 const Context& context = |
| 73 Context::ZoneHandle(Isolate::Current()->object_store()->empty_context()); | 72 Context::ZoneHandle(Isolate::Current()->object_store()->empty_context()); |
| 74 ASSERT(context.isolate() == Isolate::Current()); | 73 ASSERT(context.isolate() == Isolate::Current()); |
| 75 const Code& code = Code::Handle(function.CurrentCode()); | 74 const Code& code = Code::Handle(function.CurrentCode()); |
| 76 ASSERT(!code.IsNull()); | 75 ASSERT(!code.IsNull()); |
| 77 return entrypoint( | 76 const Array& arg_descriptor = |
| 78 code.EntryPoint(), | 77 Array::Handle(ArgumentsDescriptor::New(arguments.length(), |
| 79 ArgumentsDescriptor(arguments.length(), optional_arguments_names), | 78 optional_arguments_names)); |
| 80 arguments.data(), | 79 return entrypoint(code.EntryPoint(), arg_descriptor, arguments.data(), |
| 81 context); | 80 context); |
| 82 } | 81 } |
| 83 | 82 |
| 84 | 83 |
| 85 RawObject* DartEntry::InvokeClosure( | 84 RawObject* DartEntry::InvokeClosure( |
| 86 const Instance& closure, | 85 const Instance& closure, |
| 87 const GrowableArray<const Object*>& arguments, | 86 const GrowableArray<const Object*>& arguments, |
| 88 const Array& optional_arguments_names) { | 87 const Array& optional_arguments_names) { |
| 89 // Get the entrypoint corresponding to the closure specified, this | 88 // Get the entrypoint corresponding to the closure specified, this |
| 90 // will result in a compilation of the closure if it is not already | 89 // will result in a compilation of the closure if it is not already |
| 91 // compiled. | 90 // compiled. |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 106 args.Add(&arg0); | 105 args.Add(&arg0); |
| 107 for (int i = 1; i < num_arguments; i++) { | 106 for (int i = 1; i < num_arguments; i++) { |
| 108 args.Add(arguments[i - 1]); | 107 args.Add(arguments[i - 1]); |
| 109 } | 108 } |
| 110 // Now Call the invoke stub which will invoke the closure. | 109 // Now Call the invoke stub which will invoke the closure. |
| 111 invokestub entrypoint = reinterpret_cast<invokestub>( | 110 invokestub entrypoint = reinterpret_cast<invokestub>( |
| 112 StubCode::InvokeDartCodeEntryPoint()); | 111 StubCode::InvokeDartCodeEntryPoint()); |
| 113 ASSERT(context.isolate() == Isolate::Current()); | 112 ASSERT(context.isolate() == Isolate::Current()); |
| 114 const Code& code = Code::Handle(function.CurrentCode()); | 113 const Code& code = Code::Handle(function.CurrentCode()); |
| 115 ASSERT(!code.IsNull()); | 114 ASSERT(!code.IsNull()); |
| 116 return entrypoint( | 115 const Array& arg_descriptor = |
| 117 code.EntryPoint(), | 116 Array::Handle(ArgumentsDescriptor::New(num_arguments, |
| 118 ArgumentsDescriptor(num_arguments, optional_arguments_names), | 117 optional_arguments_names)); |
| 119 args.data(), | 118 return entrypoint(code.EntryPoint(), arg_descriptor, args.data(), context); |
| 120 context); | |
| 121 } | 119 } |
| 122 | 120 |
| 123 | 121 |
| 124 const Array& DartEntry::ArgumentsDescriptor( | 122 ArgumentsDescriptor::ArgumentsDescriptor(RawObject* array) |
| 125 int num_arguments, | 123 : array_(Array::CheckedHandle(array)) { |
| 126 const Array& optional_arguments_names) { | 124 } |
| 125 | |
| 126 | |
| 127 intptr_t ArgumentsDescriptor::Count() const { | |
| 128 return Smi::CheckedHandle(array_.At(kCountIndex)).Value(); | |
| 129 } | |
| 130 | |
| 131 | |
| 132 intptr_t ArgumentsDescriptor::PositionalCount() const { | |
| 133 return Smi::CheckedHandle(array_.At(kPositionalCountIndex)).Value(); | |
| 134 } | |
| 135 | |
| 136 | |
| 137 RawObject* ArgumentsDescriptor::NameAt(intptr_t index) const { | |
| 138 return array_.At(kFirstNamedEntryIndex + | |
| 139 (index * kNamedEntrySize) + | |
| 140 kNameOffset); | |
| 141 } | |
| 142 | |
| 143 | |
| 144 intptr_t ArgumentsDescriptor::count_offset() { | |
| 145 return Array::data_offset() + (kCountIndex * kWordSize); | |
| 146 } | |
| 147 | |
| 148 | |
| 149 intptr_t ArgumentsDescriptor::positional_count_offset() { | |
| 150 return Array::data_offset() + (kPositionalCountIndex * kWordSize); | |
| 151 } | |
| 152 | |
| 153 | |
| 154 intptr_t ArgumentsDescriptor::first_named_entry_offset() { | |
| 155 return Array::data_offset() + (kFirstNamedEntryIndex * kWordSize); | |
| 156 } | |
| 157 | |
| 158 | |
| 159 RawArray* ArgumentsDescriptor::New(intptr_t num_arguments, | |
| 160 const Array& optional_arguments_names) { | |
| 127 const intptr_t num_named_args = | 161 const intptr_t num_named_args = |
| 128 optional_arguments_names.IsNull() ? 0 : optional_arguments_names.Length(); | 162 optional_arguments_names.IsNull() ? 0 : optional_arguments_names.Length(); |
| 129 const intptr_t num_pos_args = num_arguments - num_named_args; | 163 const intptr_t num_pos_args = num_arguments - num_named_args; |
| 130 | 164 |
| 131 // Build the argument descriptor array, which consists of the total number of | 165 // Build the arguments descriptor array, which consists of the total |
| 132 // arguments, the number of positional arguments, alphabetically sorted | 166 // argument count; the positional argument count; a sequence of (name, |
| 133 // pairs of name/position, and a terminating null. | 167 // position) pairs, sorted by name, for each named optional argument; and |
| 134 const int descriptor_len = 3 + (2 * num_named_args); | 168 // a terminating null to simplify iterating in generated code. |
| 135 Array& descriptor = Array::ZoneHandle(Array::New(descriptor_len, Heap::kOld)); | 169 const intptr_t descriptor_len = LengthFor(num_named_args); |
| 170 Array& descriptor = Array::Handle(Array::New(descriptor_len, Heap::kOld)); | |
| 136 | 171 |
| 137 // Set total number of passed arguments. | 172 // Set total number of passed arguments. |
| 138 descriptor.SetAt(0, Smi::Handle(Smi::New(num_arguments))); | 173 descriptor.SetAt(kCountIndex, Smi::Handle(Smi::New(num_arguments))); |
| 139 // Set number of positional arguments. | 174 // Set number of positional arguments. |
| 140 descriptor.SetAt(1, Smi::Handle(Smi::New(num_pos_args))); | 175 descriptor.SetAt(kPositionalCountIndex, Smi::Handle(Smi::New(num_pos_args))); |
| 141 // Set alphabetically sorted pairs of name/position for named arguments. | 176 // Set alphabetically sorted entries for named arguments. |
| 142 String& name = String::Handle(); | 177 String& name = String::Handle(); |
| 143 Smi& pos = Smi::Handle(); | 178 Smi& pos = Smi::Handle(); |
| 144 for (int i = 0; i < num_named_args; i++) { | 179 for (intptr_t i = 0; i < num_named_args; i++) { |
| 145 name ^= optional_arguments_names.At(i); | 180 name ^= optional_arguments_names.At(i); |
| 146 pos = Smi::New(num_pos_args + i); | 181 pos = Smi::New(num_pos_args + i); |
| 147 int j = i; | 182 int insert_index = kFirstNamedEntryIndex + (kNamedEntrySize * i); |
|
Vyacheslav Egorov (Google)
2012/12/05 12:04:16
intptr_t
| |
| 148 // Shift already inserted pairs with "larger" names. | 183 // Shift already inserted pairs with "larger" names. |
| 149 String& name_j = String::Handle(); | 184 String& previous_name = String::Handle(); |
| 150 Smi& pos_j = Smi::Handle(); | 185 Smi& previous_pos = Smi::Handle(); |
| 151 while (--j >= 0) { | 186 while (insert_index > kFirstNamedEntryIndex) { |
| 152 name_j ^= descriptor.At(2 + (2 * j)); | 187 intptr_t previous_index = insert_index - kNamedEntrySize; |
| 153 const intptr_t result = name.CompareTo(name_j); | 188 previous_name ^= descriptor.At(previous_index + kNameOffset); |
| 189 intptr_t result = name.CompareTo(previous_name); | |
| 154 ASSERT(result != 0); // Duplicate argument names checked in parser. | 190 ASSERT(result != 0); // Duplicate argument names checked in parser. |
| 155 if (result > 0) break; | 191 if (result > 0) break; |
| 156 pos_j ^= descriptor.At(3 + (2 * j)); | 192 previous_pos ^= descriptor.At(previous_index + kPositionOffset); |
| 157 descriptor.SetAt(2 + (2 * (j + 1)), name_j); | 193 descriptor.SetAt(insert_index + kNameOffset, previous_name); |
| 158 descriptor.SetAt(3 + (2 * (j + 1)), pos_j); | 194 descriptor.SetAt(insert_index + kPositionOffset, previous_pos); |
| 195 insert_index = previous_index; | |
| 159 } | 196 } |
| 160 // Insert pair in descriptor array. | 197 // Insert pair in descriptor array. |
| 161 descriptor.SetAt(2 + (2 * (j + 1)), name); | 198 descriptor.SetAt(insert_index + kNameOffset, name); |
| 162 descriptor.SetAt(3 + (2 * (j + 1)), pos); | 199 descriptor.SetAt(insert_index + kPositionOffset, pos); |
| 163 } | 200 } |
| 164 // Set terminating null. | 201 // Set terminating null. |
| 165 descriptor.SetAt(descriptor_len - 1, Object::Handle()); | 202 descriptor.SetAt(descriptor_len - 1, Object::Handle()); |
| 166 | 203 |
| 167 // Share the immutable descriptor when possible by canonicalizing it. | 204 // Share the immutable descriptor when possible by canonicalizing it. |
| 168 descriptor.MakeImmutable(); | 205 descriptor.MakeImmutable(); |
| 169 descriptor ^= descriptor.Canonicalize(); | 206 descriptor ^= descriptor.Canonicalize(); |
| 170 return descriptor; | 207 return descriptor.raw(); |
| 171 } | 208 } |
| 172 | 209 |
| 173 | 210 |
| 174 RawObject* DartLibraryCalls::ExceptionCreate( | 211 RawObject* DartLibraryCalls::ExceptionCreate( |
| 175 const Library& lib, | 212 const Library& lib, |
| 176 const String& class_name, | 213 const String& class_name, |
| 177 const GrowableArray<const Object*>& arguments) { | 214 const GrowableArray<const Object*>& arguments) { |
| 178 const Class& cls = Class::Handle(lib.LookupClassAllowPrivate(class_name)); | 215 const Class& cls = Class::Handle(lib.LookupClassAllowPrivate(class_name)); |
| 179 ASSERT(!cls.IsNull()); | 216 ASSERT(!cls.IsNull()); |
| 180 // For now, we only support a non-parameterized or raw type. | 217 // For now, we only support a non-parameterized or raw type. |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 322 const String& func_name = String::Handle(Field::GetterName(field_name)); | 359 const String& func_name = String::Handle(Field::GetterName(field_name)); |
| 323 const Function& func = Function::Handle(cls.LookupDynamicFunction(func_name)); | 360 const Function& func = Function::Handle(cls.LookupDynamicFunction(func_name)); |
| 324 ASSERT(!func.IsNull()); | 361 ASSERT(!func.IsNull()); |
| 325 GrowableArray<const Object*> arguments; | 362 GrowableArray<const Object*> arguments; |
| 326 const Array& kNoArgumentNames = Array::Handle(); | 363 const Array& kNoArgumentNames = Array::Handle(); |
| 327 return DartEntry::InvokeDynamic(port, func, arguments, kNoArgumentNames); | 364 return DartEntry::InvokeDynamic(port, func, arguments, kNoArgumentNames); |
| 328 } | 365 } |
| 329 | 366 |
| 330 | 367 |
| 331 } // namespace dart | 368 } // namespace dart |
| OLD | NEW |