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

Side by Side Diff: src/v8natives.js

Issue 2850: Generalize the Function.prototype.call hooks in the... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 12 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 | Annotate | Revision Log
« no previous file with comments | « src/objects-inl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 } 407 }
408 var body = (n > 0) ? ToString(%_Arguments(n - 1)) : ''; 408 var body = (n > 0) ? ToString(%_Arguments(n - 1)) : '';
409 var source = '(function anonymous(' + p + ') { ' + body + ' })'; 409 var source = '(function anonymous(' + p + ') { ' + body + ' })';
410 410
411 // The call to SetNewFunctionAttributes will ensure the prototype 411 // The call to SetNewFunctionAttributes will ensure the prototype
412 // property of the resulting function is enumerable (ECMA262, 15.3.5.2). 412 // property of the resulting function is enumerable (ECMA262, 15.3.5.2).
413 return %SetNewFunctionAttributes(%CompileString(source, false)()); 413 return %SetNewFunctionAttributes(%CompileString(source, false)());
414 }; 414 };
415 415
416 %SetCode($Function, NewFunction); 416 %SetCode($Function, NewFunction);
417
418
419 // NOTE: The following functions (call and apply) are only used in this
420 // form on the ARM platform. On IA-32 they are handled through specialized
421 // builtins; see builtins-ia32.cc.
422
423 %AddProperty($Function.prototype, "call", function(receiver) {
424 // Make sure the receiver of this call is a function. If it isn't
425 // we "fake" a call of it (without the right arguments) to force
426 // an exception to be thrown.
427 if (!IS_FUNCTION(this)) this();
428
429 // If receiver is null or undefined set the receiver to the global
430 // object. If the receiver isn't an object, we convert the
431 // receiver to an object.
432 if (receiver == null) receiver = global;
433 else if (!IS_OBJECT(receiver)) receiver = ToObject(receiver);
434
435 %_SetThisFunction(this);
436 %_SetThis(receiver);
437
438 var len = %_GetArgumentsLength(1);
439 return %_ShiftDownAndTailCall(len ? len - 1 : 0);
440 }, DONT_ENUM);
441
442
443 // This implementation of Function.prototype.apply replaces the stack frame
444 // of the apply call with the new stack frame containing the arguments from
445 // the args array.
446 %AddProperty($Function.prototype, "apply", function(receiver, args) {
447 var length = (args == null) ? 0 : ToUint32(args.length);
448
449 // We can handle any number of apply arguments if the stack is
450 // big enough, but sanity check the value to avoid overflow when
451 // multiplying with pointer size.
452 if (length > 0x800000) {
453 throw new $RangeError(
454 "Function.prototype.apply cannot support " + length + " arguments.");
455 }
456
457 if (!IS_FUNCTION(this)) {
458 throw new $TypeError('Function.prototype.apply was called on ' + this.toStri ng() + ', which is a ' + (typeof this) + ' and not a function');
459 }
460
461 // Make sure args has the right type.
462 if (args != null && %ClassOf(args) !== 'Array' && %ClassOf(args) !== 'Argument s') {
463 throw new $TypeError('Function.prototype.apply: args has wrong type');
464 }
465
466 // If receiver is null or undefined set the receiver to the global
467 // object. If the receiver isn't an object, we convert the
468 // receiver to an object.
469 if (receiver == null) receiver = global;
470 else if (!IS_OBJECT(receiver)) receiver = ToObject(receiver);
471
472 %_SetThisFunction(this);
473 %_SetThis(receiver);
474
475 var arguments_length = %_GetArgumentsLength(2);
476
477 // This method has 2 formal arguments so if less are passed, then space has
478 // been made.
479 if (arguments_length < 2)
480 arguments_length = 2;
481
482 // Move some stuff to locals so they don't get overwritten when we start
483 // expanding the args array.
484 var saved_args = args;
485
486 if (arguments_length > length) {
487 // We have too many arguments - we need to squash the frame.
488 %_SquashFrame(arguments_length, length);
489 } else if (arguments_length != length) {
490 // We have too few spaces for arguments - we need to expand the frame.
491 if (!%_ExpandFrame(arguments_length, length)) {
492 throw new $RangeError(
493 "Function.prototype.apply cannot find stack space for " + length + " a rguments.");
494 }
495 // GC doesn't like junk in the arguments!
496 for (var i = 0; i < length; i++) {
497 %_SetArgument(i, 0, length);
498 }
499 }
500
501 // Update-number-of-arguments field to keep things looking consistent for
502 // stack traces, and uses of arguments or arguments.length.
503 %_SetArgumentsLength(length);
504
505 // NOTE: For the fast case this should be implemented in assembler,
506 // which would allow us to omit bounds and class checks galore. The
507 // assembler version could fall back to this implementation if
508 // tricky stuff is found, like arrays implemented as dictionaries or
509 // holes in arrays.
510 for (var i = 0; i < length; i++) {
511 %_SetArgument(i, saved_args[i], length);
512 }
513
514 // Replaces the current frame with the new call. This has the added effect
515 // of removing apply from the stack trace entirely, which matches the
516 // behaviour of Firefox.
517 return %_TailCallWithArguments(length);
518 }, DONT_ENUM);
519
520
OLDNEW
« no previous file with comments | « src/objects-inl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698