OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 #ifndef VM_NATIVE_ARGUMENTS_H_ | 5 #ifndef VM_NATIVE_ARGUMENTS_H_ |
6 #define VM_NATIVE_ARGUMENTS_H_ | 6 #define VM_NATIVE_ARGUMENTS_H_ |
7 | 7 |
8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
9 #include "vm/globals.h" | 9 #include "vm/globals.h" |
10 #include "vm/stub_code.h" | 10 #include "vm/stub_code.h" |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 // const Instance& arg0 = Instance::CheckedHandle(arguments.At(0)); | 53 // const Instance& arg0 = Instance::CheckedHandle(arguments.At(0)); |
54 // const Smi& arg1 = Smi::CheckedHandle(arguments.At(1)); | 54 // const Smi& arg1 = Smi::CheckedHandle(arguments.At(1)); |
55 // The return value is set as follows: | 55 // The return value is set as follows: |
56 // arguments.SetReturn(result); | 56 // arguments.SetReturn(result); |
57 // NOTE: Since we pass 'this' as a pass-by-value argument in the stubs we don't | 57 // NOTE: Since we pass 'this' as a pass-by-value argument in the stubs we don't |
58 // have DISALLOW_COPY_AND_ASSIGN in the class definition and do not make it a | 58 // have DISALLOW_COPY_AND_ASSIGN in the class definition and do not make it a |
59 // subclass of ValueObject. | 59 // subclass of ValueObject. |
60 class NativeArguments { | 60 class NativeArguments { |
61 public: | 61 public: |
62 Isolate* isolate() const { return isolate_; } | 62 Isolate* isolate() const { return isolate_; } |
63 int Count() const { return ArgcBits::decode(argc_tag_); } | 63 int ArgCount() const { return ArgcBits::decode(argc_tag_); } |
64 | 64 |
65 // Returns true if the arguments are those of an instance function call. | 65 // Returns true if the arguments are those of an instance function call. |
66 bool ToInstanceFunction() const { | 66 bool ToInstanceFunction() const { |
67 return InstanceFunctionBit::decode(argc_tag_); | 67 return InstanceFunctionBit::decode(argc_tag_); |
68 } | 68 } |
69 | 69 |
70 // Returns true if the arguments are those of a closure function call. | 70 // Returns true if the arguments are those of a closure function call. |
71 bool ToClosureFunction() const { | 71 bool ToClosureFunction() const { |
72 return ClosureFunctionBit::decode(argc_tag_); | 72 return ClosureFunctionBit::decode(argc_tag_); |
73 } | 73 } |
74 | 74 |
75 RawObject* At(int index) const { | 75 RawObject* ArgAt(int index) const { |
76 ASSERT(index >=0 && index < Count()); | 76 ASSERT((index >= 0) && (index < ArgCount())); |
77 return (*argv_)[-index]; | 77 return (*argv_)[-index]; |
78 } | 78 } |
79 | 79 |
| 80 int NumHiddenArgs() const { |
| 81 // For static closure functions, the closure at index 0 is hidden. |
| 82 // In the instance closure function case, the receiver is accessed from |
| 83 // the context and the closure at index 0 is hidden, so the apparent |
| 84 // argument count remains unchanged. |
| 85 if (ToClosureFunction() && !ToInstanceFunction()) { |
| 86 return 1; |
| 87 } |
| 88 return 0; |
| 89 } |
| 90 |
| 91 int NativeArgCount() const { |
| 92 return ArgCount() - NumHiddenArgs(); |
| 93 } |
| 94 |
| 95 RawObject* NativeArgAt(int index) const { |
| 96 const int num_hidden_args = NumHiddenArgs(); |
| 97 const int actual_index = index + num_hidden_args; |
| 98 ASSERT((actual_index >= num_hidden_args) && (index < ArgCount())); |
| 99 if ((index == 0) && ToClosureFunction() && ToInstanceFunction()) { |
| 100 // Retrieve the receiver from the context. |
| 101 const Context& context = Context::Handle(isolate_->top_context()); |
| 102 return context.At(0); |
| 103 } else { |
| 104 return ArgAt(actual_index); |
| 105 } |
| 106 } |
| 107 |
80 void SetReturn(const Object& value) const; | 108 void SetReturn(const Object& value) const; |
81 | 109 |
82 static intptr_t isolate_offset() { | 110 static intptr_t isolate_offset() { |
83 return OFFSET_OF(NativeArguments, isolate_); | 111 return OFFSET_OF(NativeArguments, isolate_); |
84 } | 112 } |
85 static intptr_t argc_tag_offset() { | 113 static intptr_t argc_tag_offset() { |
86 return OFFSET_OF(NativeArguments, argc_tag_); | 114 return OFFSET_OF(NativeArguments, argc_tag_); |
87 } | 115 } |
88 static intptr_t argv_offset() { return OFFSET_OF(NativeArguments, argv_); } | 116 static intptr_t argv_offset() { return OFFSET_OF(NativeArguments, argv_); } |
89 static intptr_t retval_offset() { | 117 static intptr_t retval_offset() { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 | 162 |
135 Isolate* isolate_; // Current isolate pointer. | 163 Isolate* isolate_; // Current isolate pointer. |
136 int argc_tag_; // Encodes argument count and invoked native call type. | 164 int argc_tag_; // Encodes argument count and invoked native call type. |
137 RawObject*(*argv_)[]; // Pointer to an array of arguments to runtime call. | 165 RawObject*(*argv_)[]; // Pointer to an array of arguments to runtime call. |
138 RawObject** retval_; // Pointer to the return value area. | 166 RawObject** retval_; // Pointer to the return value area. |
139 }; | 167 }; |
140 | 168 |
141 } // namespace dart | 169 } // namespace dart |
142 | 170 |
143 #endif // VM_NATIVE_ARGUMENTS_H_ | 171 #endif // VM_NATIVE_ARGUMENTS_H_ |
OLD | NEW |