Commit 72496284 authored by lrn@chromium.org's avatar lrn@chromium.org

Make built-in functions not call .apply on functions.

Uses the new %Apply runtime function instead.
Removes last(?) dependency on user-mungable infrastructure.

Review URL: http://codereview.chromium.org/7887031

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9277 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent e292eddf
...@@ -227,7 +227,7 @@ Handle<Object> Execution::GetFunctionDelegate(Handle<Object> object) { ...@@ -227,7 +227,7 @@ Handle<Object> Execution::GetFunctionDelegate(Handle<Object> object) {
// If you return a function from here, it will be called when an // If you return a function from here, it will be called when an
// attempt is made to call the given object as a function. // attempt is made to call the given object as a function.
// If object is a function proxies, get its handler. Iterate if necessary. // If object is a function proxy, get its handler. Iterate if necessary.
Object* fun = *object; Object* fun = *object;
while (fun->IsJSFunctionProxy()) { while (fun->IsJSFunctionProxy()) {
fun = JSFunctionProxy::cast(fun)->call_trap(); fun = JSFunctionProxy::cast(fun)->call_trap();
...@@ -251,7 +251,7 @@ Handle<Object> Execution::TryGetFunctionDelegate(Handle<Object> object, ...@@ -251,7 +251,7 @@ Handle<Object> Execution::TryGetFunctionDelegate(Handle<Object> object,
ASSERT(!object->IsJSFunction()); ASSERT(!object->IsJSFunction());
Isolate* isolate = Isolate::Current(); Isolate* isolate = Isolate::Current();
// If object is a function proxies, get its handler. Iterate if necessary. // If object is a function proxy, get its handler. Iterate if necessary.
Object* fun = *object; Object* fun = *object;
while (fun->IsJSFunctionProxy()) { while (fun->IsJSFunctionProxy()) {
fun = JSFunctionProxy::cast(fun)->call_trap(); fun = JSFunctionProxy::cast(fun)->call_trap();
......
...@@ -408,7 +408,7 @@ function CALL_NON_FUNCTION() { ...@@ -408,7 +408,7 @@ function CALL_NON_FUNCTION() {
if (!IS_FUNCTION(delegate)) { if (!IS_FUNCTION(delegate)) {
throw %MakeTypeError('called_non_callable', [typeof this]); throw %MakeTypeError('called_non_callable', [typeof this]);
} }
return delegate.apply(this, arguments); return %Apply(delegate, this, arguments, 0, %_ArgumentsLength());
} }
...@@ -417,7 +417,7 @@ function CALL_NON_FUNCTION_AS_CONSTRUCTOR() { ...@@ -417,7 +417,7 @@ function CALL_NON_FUNCTION_AS_CONSTRUCTOR() {
if (!IS_FUNCTION(delegate)) { if (!IS_FUNCTION(delegate)) {
throw %MakeTypeError('called_non_callable', [typeof this]); throw %MakeTypeError('called_non_callable', [typeof this]);
} }
return delegate.apply(this, arguments); return %Apply(delegate, this, arguments, 0, %_ArgumentsLength());
} }
......
...@@ -440,13 +440,14 @@ function StringReplaceGlobalRegExpWithFunction(subject, regexp, replace) { ...@@ -440,13 +440,14 @@ function StringReplaceGlobalRegExpWithFunction(subject, regexp, replace) {
i++; i++;
} }
} else { } else {
var receiver = %GetDefaultReceiver(replace);
while (i < len) { while (i < len) {
var elem = res[i]; var elem = res[i];
if (!%_IsSmi(elem)) { if (!%_IsSmi(elem)) {
// elem must be an Array. // elem must be an Array.
// Use the apply argument as backing for global RegExp properties. // Use the apply argument as backing for global RegExp properties.
lastMatchInfoOverride = elem; lastMatchInfoOverride = elem;
var func_result = replace.apply(null, elem); var func_result = %Apply(replace, receiver, elem, 0, elem.length);
res[i] = TO_STRING_INLINE(func_result); res[i] = TO_STRING_INLINE(func_result);
} }
i++; i++;
...@@ -472,11 +473,11 @@ function StringReplaceNonGlobalRegExpWithFunction(subject, regexp, replace) { ...@@ -472,11 +473,11 @@ function StringReplaceNonGlobalRegExpWithFunction(subject, regexp, replace) {
// The number of captures plus one for the match. // The number of captures plus one for the match.
var m = NUMBER_OF_CAPTURES(matchInfo) >> 1; var m = NUMBER_OF_CAPTURES(matchInfo) >> 1;
var replacement; var replacement;
var receiver = %GetDefaultReceiver(replace);
if (m == 1) { if (m == 1) {
// No captures, only the match, which is always valid. // No captures, only the match, which is always valid.
var s = SubString(subject, index, endOfMatch); var s = SubString(subject, index, endOfMatch);
// Don't call directly to avoid exposing the built-in global object. // Don't call directly to avoid exposing the built-in global object.
var receiver = %GetDefaultReceiver(replace);
replacement = replacement =
%_CallFunction(receiver, s, index, subject, replace); %_CallFunction(receiver, s, index, subject, replace);
} else { } else {
...@@ -487,7 +488,7 @@ function StringReplaceNonGlobalRegExpWithFunction(subject, regexp, replace) { ...@@ -487,7 +488,7 @@ function StringReplaceNonGlobalRegExpWithFunction(subject, regexp, replace) {
parameters[j] = index; parameters[j] = index;
parameters[j + 1] = subject; parameters[j + 1] = subject;
replacement = replace.apply(null, parameters); replacement = %Apply(replace, receiver, parameters, 0, j + 2);
} }
result.add(replacement); // The add method converts to string if necessary. result.add(replacement); // The add method converts to string if necessary.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment