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

Side by Side Diff: src/execution.cc

Issue 1316933002: [es6] Initial steps towards a correct implementation of IsCallable. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: ia32, arm and arm64 ports. Misc cleanups. 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
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/messages.h" 10 #include "src/messages.h"
11 #include "src/parser.h"
12 #include "src/prettyprinter.h"
11 #include "src/vm-state-inl.h" 13 #include "src/vm-state-inl.h"
12 14
13 namespace v8 { 15 namespace v8 {
14 namespace internal { 16 namespace internal {
15 17
16 StackGuard::StackGuard() 18 StackGuard::StackGuard()
17 : isolate_(NULL) { 19 : isolate_(NULL) {
18 } 20 }
19 21
20 22
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 } 154 }
153 155
154 156
155 MaybeHandle<Object> Execution::Call(Isolate* isolate, 157 MaybeHandle<Object> Execution::Call(Isolate* isolate,
156 Handle<Object> callable, 158 Handle<Object> callable,
157 Handle<Object> receiver, 159 Handle<Object> receiver,
158 int argc, 160 int argc,
159 Handle<Object> argv[], 161 Handle<Object> argv[],
160 bool convert_receiver) { 162 bool convert_receiver) {
161 if (!callable->IsJSFunction()) { 163 if (!callable->IsJSFunction()) {
162 ASSIGN_RETURN_ON_EXCEPTION( 164 ASSIGN_RETURN_ON_EXCEPTION(isolate, callable,
163 isolate, callable, TryGetFunctionDelegate(isolate, callable), Object); 165 GetFunctionDelegate(isolate, callable), Object);
164 } 166 }
165 Handle<JSFunction> func = Handle<JSFunction>::cast(callable); 167 Handle<JSFunction> func = Handle<JSFunction>::cast(callable);
166 168
167 // In sloppy mode, convert receiver. 169 // In sloppy mode, convert receiver.
168 if (convert_receiver && !receiver->IsJSReceiver() && 170 if (convert_receiver && !receiver->IsJSReceiver() &&
169 !func->shared()->native() && is_sloppy(func->shared()->language_mode())) { 171 !func->shared()->native() && is_sloppy(func->shared()->language_mode())) {
170 if (receiver->IsUndefined() || receiver->IsNull()) { 172 if (receiver->IsUndefined() || receiver->IsNull()) {
171 receiver = handle(func->global_proxy()); 173 receiver = handle(func->global_proxy());
172 DCHECK(!receiver->IsJSBuiltinsObject()); 174 DCHECK(!receiver->IsJSBuiltinsObject());
173 } else { 175 } else {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 DCHECK(!isolate->has_pending_exception()); 226 DCHECK(!isolate->has_pending_exception());
225 } 227 }
226 228
227 // Re-request terminate execution interrupt to trigger later. 229 // Re-request terminate execution interrupt to trigger later.
228 if (is_termination) isolate->stack_guard()->RequestTerminateExecution(); 230 if (is_termination) isolate->stack_guard()->RequestTerminateExecution();
229 231
230 return maybe_result; 232 return maybe_result;
231 } 233 }
232 234
233 235
234 Handle<Object> Execution::GetFunctionDelegate(Isolate* isolate, 236 // static
235 Handle<Object> object) { 237 MaybeHandle<JSFunction> Execution::GetFunctionDelegate(Isolate* isolate,
238 Handle<Object> object) {
236 DCHECK(!object->IsJSFunction()); 239 DCHECK(!object->IsJSFunction());
237 Factory* factory = isolate->factory(); 240 if (object->IsHeapObject()) {
241 DisallowHeapAllocation no_gc;
238 242
239 // If you return a function from here, it will be called when an 243 // If object is a function proxy, get its handler. Iterate if necessary.
240 // attempt is made to call the given object as a function. 244 Object* fun = *object;
245 while (fun->IsJSFunctionProxy()) {
246 fun = JSFunctionProxy::cast(fun)->call_trap();
247 }
248 if (fun->IsJSFunction()) {
249 return handle(JSFunction::cast(fun), isolate);
250 }
241 251
242 // If object is a function proxy, get its handler. Iterate if necessary. 252 // We can also have exotic objects with [[Call]] internal methods.
243 Object* fun = *object; 253 if (fun->IsCallable()) {
244 while (fun->IsJSFunctionProxy()) { 254 return handle(isolate->native_context()->call_as_function_delegate(),
245 fun = JSFunctionProxy::cast(fun)->call_trap(); 255 isolate);
246 } 256 }
247 if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
248
249 // Objects created through the API can have an instance-call handler
250 // that should be used when calling the object as a function.
251 if (fun->IsHeapObject() &&
252 HeapObject::cast(fun)->map()->has_instance_call_handler()) {
253 return Handle<JSFunction>(
254 isolate->native_context()->call_as_function_delegate());
255 }
256
257 return factory->undefined_value();
258 }
259
260
261 MaybeHandle<Object> Execution::TryGetFunctionDelegate(Isolate* isolate,
262 Handle<Object> object) {
263 DCHECK(!object->IsJSFunction());
264
265 // If object is a function proxy, get its handler. Iterate if necessary.
266 Object* fun = *object;
267 while (fun->IsJSFunctionProxy()) {
268 fun = JSFunctionProxy::cast(fun)->call_trap();
269 }
270 if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
271
272 // Objects created through the API can have an instance-call handler
273 // that should be used when calling the object as a function.
274 if (fun->IsHeapObject() &&
275 HeapObject::cast(fun)->map()->has_instance_call_handler()) {
276 return Handle<JSFunction>(
277 isolate->native_context()->call_as_function_delegate());
278 } 257 }
279 258
280 // If the Object doesn't have an instance-call handler we should 259 // If the Object doesn't have an instance-call handler we should
281 // throw a non-callable exception. 260 // throw a non-callable exception.
261 Handle<String> callsite = RenderCallSite(isolate, object);
282 THROW_NEW_ERROR(isolate, 262 THROW_NEW_ERROR(isolate,
283 NewTypeError(MessageTemplate::kCalledNonCallable, object), 263 NewTypeError(MessageTemplate::kCalledNonCallable, callsite),
284 Object); 264 JSFunction);
285 } 265 }
286 266
287 267
288 Handle<Object> Execution::GetConstructorDelegate(Isolate* isolate, 268 // static
289 Handle<Object> object) { 269 MaybeHandle<JSFunction> Execution::GetConstructorDelegate(
290 DCHECK(!object->IsJSFunction()); 270 Isolate* isolate, Handle<Object> object) {
291
292 // If you return a function from here, it will be called when an 271 // If you return a function from here, it will be called when an
293 // attempt is made to call the given object as a constructor. 272 // attempt is made to call the given object as a constructor.
294 273
295 // If object is a function proxies, get its handler. Iterate if necessary. 274 DCHECK(!object->IsJSFunction());
296 Object* fun = *object; 275 if (object->IsHeapObject()) {
297 while (fun->IsJSFunctionProxy()) { 276 DisallowHeapAllocation no_gc;
298 fun = JSFunctionProxy::cast(fun)->call_trap();
299 }
300 if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
301 277
302 // Objects created through the API can have an instance-call handler 278 // If object is a function proxies, get its handler. Iterate if necessary.
303 // that should be used when calling the object as a function. 279 Object* fun = *object;
304 if (fun->IsHeapObject() && 280 while (fun->IsJSFunctionProxy()) {
305 HeapObject::cast(fun)->map()->has_instance_call_handler()) { 281 // TODO(bmeurer): This should work based on [[Construct]]; our proxies
306 return Handle<JSFunction>( 282 // are screwed.
307 isolate->native_context()->call_as_constructor_delegate()); 283 fun = JSFunctionProxy::cast(fun)->call_trap();
308 } 284 }
285 if (fun->IsJSFunction()) {
286 return handle(JSFunction::cast(fun), isolate);
287 }
309 288
310 return isolate->factory()->undefined_value(); 289 // We can also have exotic objects with [[Construct]] internal methods.
311 } 290 // TODO(bmeurer): This should use IsConstructor() as dictacted by the spec.
312 291 if (fun->IsCallable()) {
313 292 return handle(isolate->native_context()->call_as_constructor_delegate(),
314 MaybeHandle<Object> Execution::TryGetConstructorDelegate( 293 isolate);
315 Isolate* isolate, Handle<Object> object) { 294 }
316 DCHECK(!object->IsJSFunction());
317
318 // If you return a function from here, it will be called when an
319 // attempt is made to call the given object as a constructor.
320
321 // If object is a function proxies, get its handler. Iterate if necessary.
322 Object* fun = *object;
323 while (fun->IsJSFunctionProxy()) {
324 fun = JSFunctionProxy::cast(fun)->call_trap();
325 }
326 if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
327
328 // Objects created through the API can have an instance-call handler
329 // that should be used when calling the object as a function.
330 if (fun->IsHeapObject() &&
331 HeapObject::cast(fun)->map()->has_instance_call_handler()) {
332 return Handle<JSFunction>(
333 isolate->native_context()->call_as_constructor_delegate());
334 } 295 }
335 296
336 // If the Object doesn't have an instance-call handler we should 297 // If the Object doesn't have an instance-call handler we should
337 // throw a non-callable exception. 298 // throw a non-callable exception.
299 Handle<String> callsite = RenderCallSite(isolate, object);
338 THROW_NEW_ERROR(isolate, 300 THROW_NEW_ERROR(isolate,
339 NewTypeError(MessageTemplate::kCalledNonCallable, object), 301 NewTypeError(MessageTemplate::kCalledNonCallable, callsite),
340 Object); 302 JSFunction);
341 } 303 }
342 304
343 305
306 // static
307 Handle<String> Execution::RenderCallSite(Isolate* isolate,
308 Handle<Object> object) {
309 MessageLocation location;
310 if (isolate->ComputeLocation(&location)) {
311 Zone zone;
312 base::SmartPointer<ParseInfo> info(
313 location.function()->shared()->is_function()
314 ? new ParseInfo(&zone, location.function())
315 : new ParseInfo(&zone, location.script()));
316 if (Parser::ParseStatic(info.get())) {
317 CallPrinter printer(isolate, &zone);
318 const char* string = printer.Print(info->literal(), location.start_pos());
319 return isolate->factory()->NewStringFromAsciiChecked(string);
320 } else {
321 isolate->clear_pending_exception();
322 }
323 }
324 return Object::TypeOf(isolate, object);
325 }
326
327
344 void StackGuard::SetStackLimit(uintptr_t limit) { 328 void StackGuard::SetStackLimit(uintptr_t limit) {
345 ExecutionAccess access(isolate_); 329 ExecutionAccess access(isolate_);
346 // If the current limits are special (e.g. due to a pending interrupt) then 330 // If the current limits are special (e.g. due to a pending interrupt) then
347 // leave them alone. 331 // leave them alone.
348 uintptr_t jslimit = SimulatorStack::JsLimitFromCLimit(isolate_, limit); 332 uintptr_t jslimit = SimulatorStack::JsLimitFromCLimit(isolate_, limit);
349 if (thread_local_.jslimit() == thread_local_.real_jslimit_) { 333 if (thread_local_.jslimit() == thread_local_.real_jslimit_) {
350 thread_local_.set_jslimit(jslimit); 334 thread_local_.set_jslimit(jslimit);
351 } 335 }
352 if (thread_local_.climit() == thread_local_.real_climit_) { 336 if (thread_local_.climit() == thread_local_.real_climit_) {
353 thread_local_.set_climit(limit); 337 thread_local_.set_climit(limit);
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 659
676 isolate_->counters()->stack_interrupts()->Increment(); 660 isolate_->counters()->stack_interrupts()->Increment();
677 isolate_->counters()->runtime_profiler_ticks()->Increment(); 661 isolate_->counters()->runtime_profiler_ticks()->Increment();
678 isolate_->runtime_profiler()->OptimizeNow(); 662 isolate_->runtime_profiler()->OptimizeNow();
679 663
680 return isolate_->heap()->undefined_value(); 664 return isolate_->heap()->undefined_value();
681 } 665 }
682 666
683 } // namespace internal 667 } // namespace internal
684 } // namespace v8 668 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698