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

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

Powered by Google App Engine
This is Rietveld 408576698