Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(52)

Side by Side Diff: src/execution.cc

Issue 1353723002: [runtime] Initial step towards switching Execution::Call to callable. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Handle sloppy mode api functions correctly. Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/execution.h ('k') | src/ia32/builtins-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/execution.h" 5 #include "src/execution.h"
6 6
7 #include "src/bootstrapper.h" 7 #include "src/bootstrapper.h"
8 #include "src/codegen.h" 8 #include "src/codegen.h"
9 #include "src/deoptimizer.h" 9 #include "src/deoptimizer.h"
10 #include "src/isolate-inl.h" 10 #include "src/isolate-inl.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 Object* name = Script::cast(script)->name(); 46 Object* name = Script::cast(script)->name();
47 if (name->IsString()) { 47 if (name->IsString()) {
48 PrintF(": %s", String::cast(name)->ToCString().get()); 48 PrintF(": %s", String::cast(name)->ToCString().get());
49 } 49 }
50 } 50 }
51 PrintF("]\n"); 51 PrintF("]\n");
52 } 52 }
53 } 53 }
54 54
55 55
56 MUST_USE_RESULT static MaybeHandle<Object> Invoke( 56 namespace {
57 bool is_construct, 57
58 Handle<JSFunction> function, 58 MUST_USE_RESULT MaybeHandle<Object> Invoke(bool is_construct,
59 Handle<Object> receiver, 59 Handle<JSFunction> function,
60 int argc, 60 Handle<Object> receiver, int argc,
61 Handle<Object> args[]) { 61 Handle<Object> args[]) {
62 Isolate* isolate = function->GetIsolate(); 62 Isolate* const isolate = function->GetIsolate();
63
64 // Convert calls on global objects to be calls on the global
65 // receiver instead to avoid having a 'this' pointer which refers
66 // directly to a global object.
67 if (receiver->IsGlobalObject()) {
68 receiver =
69 handle(Handle<GlobalObject>::cast(receiver)->global_proxy(), isolate);
70 }
63 71
64 // api callbacks can be called directly. 72 // api callbacks can be called directly.
65 if (!is_construct && function->shared()->IsApiFunction()) { 73 if (!is_construct && function->shared()->IsApiFunction()) {
66 SaveContext save(isolate); 74 SaveContext save(isolate);
67 isolate->set_context(function->context()); 75 isolate->set_context(function->context());
68 if (receiver->IsGlobalObject()) { 76 // Do proper receiver conversion for non-strict mode api functions.
69 receiver = handle(Handle<GlobalObject>::cast(receiver)->global_proxy()); 77 if (!receiver->IsJSReceiver() &&
78 is_sloppy(function->shared()->language_mode())) {
79 if (receiver->IsUndefined() || receiver->IsNull()) {
80 receiver = handle(function->global_proxy(), isolate);
81 } else {
82 ASSIGN_RETURN_ON_EXCEPTION(
83 isolate, receiver, Execution::ToObject(isolate, receiver), Object);
84 }
70 } 85 }
71 DCHECK(function->context()->global_object()->IsGlobalObject()); 86 DCHECK(function->context()->global_object()->IsGlobalObject());
72 auto value = Builtins::InvokeApiFunction(function, receiver, argc, args); 87 auto value = Builtins::InvokeApiFunction(function, receiver, argc, args);
73 bool has_exception = value.is_null(); 88 bool has_exception = value.is_null();
74 DCHECK(has_exception == isolate->has_pending_exception()); 89 DCHECK(has_exception == isolate->has_pending_exception());
75 if (has_exception) { 90 if (has_exception) {
76 isolate->ReportPendingMessages(); 91 isolate->ReportPendingMessages();
77 return MaybeHandle<Object>(); 92 return MaybeHandle<Object>();
78 } else { 93 } else {
79 isolate->clear_pending_message(); 94 isolate->clear_pending_message();
(...skipping 16 matching lines...) Expand all
96 typedef Object* (*JSEntryFunction)(byte* entry, 111 typedef Object* (*JSEntryFunction)(byte* entry,
97 Object* function, 112 Object* function,
98 Object* receiver, 113 Object* receiver,
99 int argc, 114 int argc,
100 Object*** args); 115 Object*** args);
101 116
102 Handle<Code> code = is_construct 117 Handle<Code> code = is_construct
103 ? isolate->factory()->js_construct_entry_code() 118 ? isolate->factory()->js_construct_entry_code()
104 : isolate->factory()->js_entry_code(); 119 : isolate->factory()->js_entry_code();
105 120
106 // Convert calls on global objects to be calls on the global
107 // receiver instead to avoid having a 'this' pointer which refers
108 // directly to a global object.
109 if (receiver->IsGlobalObject()) {
110 receiver = handle(Handle<GlobalObject>::cast(receiver)->global_proxy());
111 }
112
113 // Make sure that the global object of the context we're about to 121 // Make sure that the global object of the context we're about to
114 // make the current one is indeed a global object. 122 // make the current one is indeed a global object.
115 DCHECK(function->context()->global_object()->IsGlobalObject()); 123 DCHECK(function->context()->global_object()->IsGlobalObject());
116 124
117 { 125 {
118 // Save and restore context around invocation and block the 126 // Save and restore context around invocation and block the
119 // allocation of handles without explicit handle scopes. 127 // allocation of handles without explicit handle scopes.
120 SaveContext save(isolate); 128 SaveContext save(isolate);
121 SealHandleScope shs(isolate); 129 SealHandleScope shs(isolate);
122 JSEntryFunction stub_entry = FUNCTION_CAST<JSEntryFunction>(code->entry()); 130 JSEntryFunction stub_entry = FUNCTION_CAST<JSEntryFunction>(code->entry());
123 131
124 // Call the function through the right JS entry stub. 132 // Call the function through the right JS entry stub.
125 byte* function_entry = function->code()->entry(); 133 byte* ignored = nullptr; // TODO(bmeurer): Remove this altogether.
126 JSFunction* func = *function; 134 JSFunction* func = *function;
127 Object* recv = *receiver; 135 Object* recv = *receiver;
128 Object*** argv = reinterpret_cast<Object***>(args); 136 Object*** argv = reinterpret_cast<Object***>(args);
129 if (FLAG_profile_deserialization) PrintDeserializedCodeInfo(function); 137 if (FLAG_profile_deserialization) PrintDeserializedCodeInfo(function);
130 value = 138 value = CALL_GENERATED_CODE(stub_entry, ignored, func, recv, argc, argv);
131 CALL_GENERATED_CODE(stub_entry, function_entry, func, recv, argc, argv);
132 } 139 }
133 140
134 #ifdef VERIFY_HEAP 141 #ifdef VERIFY_HEAP
135 if (FLAG_verify_heap) { 142 if (FLAG_verify_heap) {
136 value->ObjectVerify(); 143 value->ObjectVerify();
137 } 144 }
138 #endif 145 #endif
139 146
140 // Update the pending exception flag and return the value. 147 // Update the pending exception flag and return the value.
141 bool has_exception = value->IsException(); 148 bool has_exception = value->IsException();
142 DCHECK(has_exception == isolate->has_pending_exception()); 149 DCHECK(has_exception == isolate->has_pending_exception());
143 if (has_exception) { 150 if (has_exception) {
144 isolate->ReportPendingMessages(); 151 isolate->ReportPendingMessages();
145 // Reset stepping state when script exits with uncaught exception. 152 // Reset stepping state when script exits with uncaught exception.
146 if (isolate->debug()->is_active()) { 153 if (isolate->debug()->is_active()) {
147 isolate->debug()->ClearStepping(); 154 isolate->debug()->ClearStepping();
148 } 155 }
149 return MaybeHandle<Object>(); 156 return MaybeHandle<Object>();
150 } else { 157 } else {
151 isolate->clear_pending_message(); 158 isolate->clear_pending_message();
152 } 159 }
153 160
154 return Handle<Object>(value, isolate); 161 return Handle<Object>(value, isolate);
155 } 162 }
156 163
164 } // namespace
157 165
158 MaybeHandle<Object> Execution::Call(Isolate* isolate, 166
159 Handle<Object> callable, 167 MaybeHandle<Object> Execution::Call(Isolate* isolate, Handle<Object> callable,
160 Handle<Object> receiver, 168 Handle<Object> receiver, int argc,
161 int argc, 169 Handle<Object> argv[]) {
162 Handle<Object> argv[],
163 bool convert_receiver) {
164 if (!callable->IsJSFunction()) { 170 if (!callable->IsJSFunction()) {
165 ASSIGN_RETURN_ON_EXCEPTION(isolate, callable, 171 ASSIGN_RETURN_ON_EXCEPTION(isolate, callable,
166 GetFunctionDelegate(isolate, callable), Object); 172 GetFunctionDelegate(isolate, callable), Object);
167 } 173 }
168 Handle<JSFunction> func = Handle<JSFunction>::cast(callable); 174 Handle<JSFunction> func = Handle<JSFunction>::cast(callable);
169 175
170 // In sloppy mode, convert receiver.
171 if (convert_receiver && !receiver->IsJSReceiver() &&
172 !func->shared()->native() && is_sloppy(func->shared()->language_mode())) {
173 if (receiver->IsUndefined() || receiver->IsNull()) {
174 receiver = handle(func->global_proxy());
175 DCHECK(!receiver->IsJSBuiltinsObject());
176 } else {
177 ASSIGN_RETURN_ON_EXCEPTION(
178 isolate, receiver, ToObject(isolate, receiver), Object);
179 }
180 }
181
182 return Invoke(false, func, receiver, argc, argv); 176 return Invoke(false, func, receiver, argc, argv);
183 } 177 }
184 178
185 179
186 MaybeHandle<Object> Execution::New(Handle<JSFunction> func, 180 MaybeHandle<Object> Execution::New(Handle<JSFunction> func,
187 int argc, 181 int argc,
188 Handle<Object> argv[]) { 182 Handle<Object> argv[]) {
189 return Invoke(true, func, handle(func->global_proxy()), argc, argv); 183 return Invoke(true, func, handle(func->global_proxy()), argc, argv);
190 } 184 }
191 185
192 186
193 MaybeHandle<Object> Execution::TryCall(Handle<JSFunction> func, 187 MaybeHandle<Object> Execution::TryCall(Handle<JSFunction> func,
194 Handle<Object> receiver, int argc, 188 Handle<Object> receiver, int argc,
195 Handle<Object> args[], 189 Handle<Object> args[],
196 MaybeHandle<Object>* exception_out) { 190 MaybeHandle<Object>* exception_out) {
197 bool is_termination = false; 191 bool is_termination = false;
198 Isolate* isolate = func->GetIsolate(); 192 Isolate* isolate = func->GetIsolate();
199 MaybeHandle<Object> maybe_result; 193 MaybeHandle<Object> maybe_result;
200 if (exception_out != NULL) *exception_out = MaybeHandle<Object>(); 194 if (exception_out != NULL) *exception_out = MaybeHandle<Object>();
201 // Enter a try-block while executing the JavaScript code. To avoid 195 // Enter a try-block while executing the JavaScript code. To avoid
202 // duplicate error printing it must be non-verbose. Also, to avoid 196 // duplicate error printing it must be non-verbose. Also, to avoid
203 // creating message objects during stack overflow we shouldn't 197 // creating message objects during stack overflow we shouldn't
204 // capture messages. 198 // capture messages.
205 { 199 {
206 v8::TryCatch catcher(reinterpret_cast<v8::Isolate*>(isolate)); 200 v8::TryCatch catcher(reinterpret_cast<v8::Isolate*>(isolate));
207 catcher.SetVerbose(false); 201 catcher.SetVerbose(false);
208 catcher.SetCaptureMessage(false); 202 catcher.SetCaptureMessage(false);
209 203
210 maybe_result = Invoke(false, func, receiver, argc, args); 204 maybe_result = Call(isolate, func, receiver, argc, args);
211 205
212 if (maybe_result.is_null()) { 206 if (maybe_result.is_null()) {
213 DCHECK(catcher.HasCaught()); 207 DCHECK(catcher.HasCaught());
214 DCHECK(isolate->has_pending_exception()); 208 DCHECK(isolate->has_pending_exception());
215 DCHECK(isolate->external_caught_exception()); 209 DCHECK(isolate->external_caught_exception());
216 if (isolate->pending_exception() == 210 if (isolate->pending_exception() ==
217 isolate->heap()->termination_exception()) { 211 isolate->heap()->termination_exception()) {
218 is_termination = true; 212 is_termination = true;
219 } else { 213 } else {
220 if (exception_out != NULL) { 214 if (exception_out != NULL) {
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
646 640
647 isolate_->counters()->stack_interrupts()->Increment(); 641 isolate_->counters()->stack_interrupts()->Increment();
648 isolate_->counters()->runtime_profiler_ticks()->Increment(); 642 isolate_->counters()->runtime_profiler_ticks()->Increment();
649 isolate_->runtime_profiler()->OptimizeNow(); 643 isolate_->runtime_profiler()->OptimizeNow();
650 644
651 return isolate_->heap()->undefined_value(); 645 return isolate_->heap()->undefined_value();
652 } 646 }
653 647
654 } // namespace internal 648 } // namespace internal
655 } // namespace v8 649 } // namespace v8
OLDNEW
« no previous file with comments | « src/execution.h ('k') | src/ia32/builtins-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698