}
+void CallTrampolineDescriptor::InitializePlatformSpecific(
+ CallInterfaceDescriptorData* data) {
+ // r0 : number of arguments
+ // r1 : the target to call
+ Register registers[] = {r1, r0};
+ data->InitializePlatformSpecific(arraysize(registers), registers);
+}
+
+
void RegExpConstructResultDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {r2, r1, r0};
}
+void CallTrampolineDescriptor::InitializePlatformSpecific(
+ CallInterfaceDescriptorData* data) {
+ // x1: target
+ // x0: number of arguments
+ Register registers[] = {x1, x0};
+ data->InitializePlatformSpecific(arraysize(registers), registers);
+}
+
+
void RegExpConstructResultDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// x2: length
if (!IS_CALLABLE(func)) {
return %_CallFunction(array, ObjectToString);
}
- return %_CallFunction(array, func);
+ return %_Call(func, array);
}
var element = a[i];
for (var j = i - 1; j >= from; j--) {
var tmp = a[j];
- var order = %_CallFunction(UNDEFINED, tmp, element, comparefn);
+ var order = comparefn(tmp, element);
if (order > 0) {
a[j + 1] = tmp;
} else {
t_array[j] = [i, a[i]];
}
%_CallFunction(t_array, function(a, b) {
- return %_CallFunction(UNDEFINED, a[1], b[1], comparefn);
+ return comparefn(a[1], b[1]);
}, ArraySort);
var third_index = t_array[t_array.length >> 1][0];
return third_index;
var v0 = a[from];
var v1 = a[to - 1];
var v2 = a[third_index];
- var c01 = %_CallFunction(UNDEFINED, v0, v1, comparefn);
+ var c01 = comparefn(v0, v1);
if (c01 > 0) {
// v1 < v0, so swap them.
var tmp = v0;
v0 = v1;
v1 = tmp;
} // v0 <= v1.
- var c02 = %_CallFunction(UNDEFINED, v0, v2, comparefn);
+ var c02 = comparefn(v0, v2);
if (c02 >= 0) {
// v2 <= v0 <= v1.
var tmp = v0;
v1 = tmp;
} else {
// v0 <= v1 && v0 < v2
- var c12 = %_CallFunction(UNDEFINED, v1, v2, comparefn);
+ var c12 = comparefn(v1, v2);
if (c12 > 0) {
// v0 <= v2 < v1
var tmp = v1;
// From i to high_start are elements that haven't been compared yet.
partition: for (var i = low_end + 1; i < high_start; i++) {
var element = a[i];
- var order = %_CallFunction(UNDEFINED, element, pivot, comparefn);
+ var order = comparefn(element, pivot);
if (order < 0) {
a[i] = a[low_end];
a[low_end] = element;
high_start--;
if (high_start == i) break partition;
var top_elem = a[high_start];
- order = %_CallFunction(UNDEFINED, top_elem, pivot, comparefn);
+ order = comparefn(top_elem, pivot);
} while (order > 0);
a[i] = a[high_start];
a[high_start] = element;
// or delete elements from the array.
function InnerArrayFilter(f, receiver, array, length) {
if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
- var needs_wrapper = false;
- if (IS_NULL(receiver)) {
- if (%IsSloppyModeFunction(f)) receiver = UNDEFINED;
- } else if (!IS_UNDEFINED(receiver)) {
- needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver);
- }
var accumulator = new InternalArray();
var accumulator_length = 0;
var element = array[i];
// Prepare break slots for debugger step in.
if (stepping) %DebugPrepareStepInIfStepping(f);
- var new_receiver = needs_wrapper ? TO_OBJECT(receiver) : receiver;
- if (%_CallFunction(new_receiver, element, i, array, f)) {
+ if (%_Call(f, receiver, element, i, array)) {
accumulator[accumulator_length++] = element;
}
}
function InnerArrayForEach(f, receiver, array, length) {
if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
- var needs_wrapper = false;
- if (IS_NULL(receiver)) {
- if (%IsSloppyModeFunction(f)) receiver = UNDEFINED;
- } else if (!IS_UNDEFINED(receiver)) {
- needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver);
- }
var is_array = IS_ARRAY(array);
var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f);
var element = array[i];
// Prepare break slots for debugger step in.
if (stepping) %DebugPrepareStepInIfStepping(f);
- var new_receiver = needs_wrapper ? TO_OBJECT(receiver) : receiver;
- %_CallFunction(new_receiver, element, i, array, f);
+ %_Call(f, receiver, element, i, array);
}
}
}
function InnerArraySome(f, receiver, array, length) {
if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
- var needs_wrapper = false;
- if (IS_NULL(receiver)) {
- if (%IsSloppyModeFunction(f)) receiver = UNDEFINED;
- } else if (!IS_UNDEFINED(receiver)) {
- needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver);
- }
var is_array = IS_ARRAY(array);
var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f);
var element = array[i];
// Prepare break slots for debugger step in.
if (stepping) %DebugPrepareStepInIfStepping(f);
- var new_receiver = needs_wrapper ? TO_OBJECT(receiver) : receiver;
- if (%_CallFunction(new_receiver, element, i, array, f)) return true;
+ if (%_Call(f, receiver, element, i, array)) return true;
}
}
return false;
function InnerArrayEvery(f, receiver, array, length) {
if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
- var needs_wrapper = false;
- if (IS_NULL(receiver)) {
- if (%IsSloppyModeFunction(f)) receiver = UNDEFINED;
- } else if (!IS_UNDEFINED(receiver)) {
- needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver);
- }
var is_array = IS_ARRAY(array);
var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f);
var element = array[i];
// Prepare break slots for debugger step in.
if (stepping) %DebugPrepareStepInIfStepping(f);
- var new_receiver = needs_wrapper ? TO_OBJECT(receiver) : receiver;
- if (!%_CallFunction(new_receiver, element, i, array, f)) return false;
+ if (!%_Call(f, receiver, element, i, array)) return false;
}
}
return true;
function InnerArrayMap(f, receiver, array, length) {
if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
- var needs_wrapper = false;
- if (IS_NULL(receiver)) {
- if (%IsSloppyModeFunction(f)) receiver = UNDEFINED;
- } else if (!IS_UNDEFINED(receiver)) {
- needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver);
- }
var accumulator = new InternalArray(length);
var is_array = IS_ARRAY(array);
var element = array[i];
// Prepare break slots for debugger step in.
if (stepping) %DebugPrepareStepInIfStepping(f);
- var new_receiver = needs_wrapper ? TO_OBJECT(receiver) : receiver;
- accumulator[i] = %_CallFunction(new_receiver, element, i, array, f);
+ accumulator[i] = %_Call(f, receiver, element, i, array);
}
}
return accumulator;
var element = array[i];
// Prepare break slots for debugger step in.
if (stepping) %DebugPrepareStepInIfStepping(callback);
- current = %_CallFunction(UNDEFINED, current, element, i, array, callback);
+ current = callback(current, element, i, array);
}
}
return current;
var element = array[i];
// Prepare break slots for debugger step in.
if (stepping) %DebugPrepareStepInIfStepping(callback);
- current = %_CallFunction(UNDEFINED, current, element, i, array, callback);
+ current = callback(current, element, i, array);
}
}
return current;
}
for (var value of iterable) {
- %_CallFunction(this, value, adder);
+ %_Call(adder, this, value);
}
}
}
}
if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
- var needs_wrapper = false;
- if (IS_NULL(receiver)) {
- if (%IsSloppyModeFunction(f)) receiver = UNDEFINED;
- } else if (!IS_UNDEFINED(receiver)) {
- needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver);
- }
var iterator = new SetIterator(this, ITERATOR_KIND_VALUES);
var key;
while (%SetIteratorNext(iterator, value_array)) {
if (stepping) %DebugPrepareStepInIfStepping(f);
key = value_array[0];
- var new_receiver = needs_wrapper ? TO_OBJECT(receiver) : receiver;
- %_CallFunction(new_receiver, key, key, this, f);
+ %_Call(f, receiver, key, key, this);
}
}
if (!IS_SPEC_OBJECT(nextItem)) {
throw MakeTypeError(kIteratorValueNotAnObject, nextItem);
}
- %_CallFunction(this, nextItem[0], nextItem[1], adder);
+ %_Call(adder, this, nextItem[0], nextItem[1]);
}
}
}
}
if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
- var needs_wrapper = false;
- if (IS_NULL(receiver)) {
- if (%IsSloppyModeFunction(f)) receiver = UNDEFINED;
- } else if (!IS_UNDEFINED(receiver)) {
- needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver);
- }
var iterator = new MapIterator(this, ITERATOR_KIND_ENTRIES);
var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f);
var value_array = [UNDEFINED, UNDEFINED];
while (%MapIteratorNext(iterator, value_array)) {
if (stepping) %DebugPrepareStepInIfStepping(f);
- var new_receiver = needs_wrapper ? TO_OBJECT(receiver) : receiver;
- %_CallFunction(new_receiver, value_array[1], value_array[0], this, f);
+ %_Call(f, receiver, value_array[1], value_array[0], this);
}
}
for (var i = 0; i < length; i += 2) {
var key = array[i];
var value = array[i + 1];
- %_CallFunction(map, key, value, MapSet);
+ %_Call(MapSet, map, key, value);
}
return map;
};
var set = new GlobalSet;
var length = array.length;
for (var i = 0; i < length; ++i) {
- %_CallFunction(set, array[i], SetAdd);
+ %_Call(SetAdd, set, array[i]);
}
return set;
};
case Runtime::kTraceExit:
return 0;
case Runtime::kInlineArguments:
+ case Runtime::kInlineCall:
case Runtime::kInlineCallFunction:
case Runtime::kInlineDefaultConstructorCallSuper:
case Runtime::kInlineGetCallerJSFunction:
}
+void FullCodeGenerator::EmitCall(CallRuntime* expr) {
+ ZoneList<Expression*>* args = expr->arguments();
+ DCHECK_LE(2, args->length());
+ // Push target, receiver and arguments onto the stack.
+ for (Expression* const arg : *args) {
+ VisitForStackValue(arg);
+ }
+ // Move target to r1.
+ int const argc = args->length() - 2;
+ __ ldr(r1, MemOperand(sp, (argc + 1) * kPointerSize));
+ // Call the target.
+ __ mov(r0, Operand(argc));
+ __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
+ // Restore context register.
+ __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+ // Discard the function left on TOS.
+ context()->DropAndPlug(1, r0);
+}
+
+
void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() >= 2);
__ bind(&runtime);
__ push(r0);
- __ CallRuntime(Runtime::kCall, args->length());
+ __ CallRuntime(Runtime::kCallFunction, args->length());
__ bind(&done);
context()->Plug(r0);
}
+void FullCodeGenerator::EmitCall(CallRuntime* expr) {
+ ASM_LOCATION("FullCodeGenerator::EmitCallFunction");
+ ZoneList<Expression*>* args = expr->arguments();
+ DCHECK_LE(2, args->length());
+ // Push target, receiver and arguments onto the stack.
+ for (Expression* const arg : *args) {
+ VisitForStackValue(arg);
+ }
+ // Move target to x1.
+ int const argc = args->length() - 2;
+ __ Peek(x1, (argc + 1) * kXRegSize);
+ // Call the target.
+ __ Mov(x0, argc);
+ __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
+ // Restore context register.
+ __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+ // Discard the function left on TOS.
+ context()->DropAndPlug(1, x0);
+}
+
+
void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
ASM_LOCATION("FullCodeGenerator::EmitCallFunction");
ZoneList<Expression*>* args = expr->arguments();
__ Bind(&runtime);
__ Push(x0);
- __ CallRuntime(Runtime::kCall, args->length());
+ __ CallRuntime(Runtime::kCallFunction, args->length());
__ Bind(&done);
context()->Plug(x0);
F(IsRegExp) \
F(IsJSProxy) \
F(IsConstructCall) \
+ F(Call) \
F(CallFunction) \
F(DefaultConstructorCallSuper) \
F(ArgumentsLength) \
}
+void FullCodeGenerator::EmitCall(CallRuntime* expr) {
+ ZoneList<Expression*>* args = expr->arguments();
+ DCHECK_LE(2, args->length());
+ // Push target, receiver and arguments onto the stack.
+ for (Expression* const arg : *args) {
+ VisitForStackValue(arg);
+ }
+ // Move target to edi.
+ int const argc = args->length() - 2;
+ __ mov(edi, Operand(esp, (argc + 1) * kPointerSize));
+ // Call the target.
+ __ mov(eax, Immediate(argc));
+ __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
+ // Restore context register.
+ __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
+ // Discard the function left on TOS.
+ context()->DropAndPlug(1, eax);
+}
+
+
void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() >= 2);
__ bind(&runtime);
__ push(eax);
- __ CallRuntime(Runtime::kCall, args->length());
+ __ CallRuntime(Runtime::kCallFunction, args->length());
__ bind(&done);
context()->Plug(eax);
}
+void FullCodeGenerator::EmitCall(CallRuntime* expr) {
+ ZoneList<Expression*>* args = expr->arguments();
+ DCHECK_LE(2, args->length());
+ // Push target, receiver and arguments onto the stack.
+ for (Expression* const arg : *args) {
+ VisitForStackValue(arg);
+ }
+ // Move target to a1.
+ int const argc = args->length() - 2;
+ __ lw(a1, MemOperand(sp, (argc + 1) * kPointerSize));
+ // Call the target.
+ __ li(a0, Operand(argc));
+ __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
+ // Restore context register.
+ __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+ // Discard the function left on TOS.
+ context()->DropAndPlug(1, v0);
+}
+
+
void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() >= 2);
__ bind(&runtime);
__ push(v0);
- __ CallRuntime(Runtime::kCall, args->length());
+ __ CallRuntime(Runtime::kCallFunction, args->length());
__ bind(&done);
context()->Plug(v0);
}
+void FullCodeGenerator::EmitCall(CallRuntime* expr) {
+ ZoneList<Expression*>* args = expr->arguments();
+ DCHECK_LE(2, args->length());
+ // Push target, receiver and arguments onto the stack.
+ for (Expression* const arg : *args) {
+ VisitForStackValue(arg);
+ }
+ // Move target to a1.
+ int const argc = args->length() - 2;
+ __ ld(a1, MemOperand(sp, (argc + 1) * kPointerSize));
+ // Call the target.
+ __ li(a0, Operand(argc));
+ __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
+ // Restore context register.
+ __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+ // Discard the function left on TOS.
+ context()->DropAndPlug(1, v0);
+}
+
+
void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() >= 2);
__ bind(&runtime);
__ push(v0);
- __ CallRuntime(Runtime::kCall, args->length());
+ __ CallRuntime(Runtime::kCallFunction, args->length());
__ bind(&done);
context()->Plug(v0);
}
+void FullCodeGenerator::EmitCall(CallRuntime* expr) {
+ ZoneList<Expression*>* args = expr->arguments();
+ DCHECK_LE(2, args->length());
+ // Push target, receiver and arguments onto the stack.
+ for (Expression* const arg : *args) {
+ VisitForStackValue(arg);
+ }
+ // Move target to rdi.
+ int const argc = args->length() - 2;
+ __ movp(rdi, Operand(rsp, (argc + 1) * kPointerSize));
+ // Call the target.
+ __ Set(rax, argc);
+ __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
+ // Restore context register.
+ __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
+ // Discard the function left on TOS.
+ context()->DropAndPlug(1, rax);
+}
+
+
void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() >= 2);
__ bind(&runtime);
__ Push(rax);
- __ CallRuntime(Runtime::kCall, args->length());
+ __ CallRuntime(Runtime::kCallFunction, args->length());
__ bind(&done);
context()->Plug(rax);
throw MakeTypeError(kCalledNonCallable, predicate);
}
- var needs_wrapper = false;
- if (IS_NULL(thisArg)) {
- if (%IsSloppyModeFunction(predicate)) thisArg = UNDEFINED;
- } else if (!IS_UNDEFINED(thisArg)) {
- needs_wrapper = SHOULD_CREATE_WRAPPER(predicate, thisArg);
- }
-
for (var i = 0; i < length; i++) {
var element = array[i];
- var newThisArg = needs_wrapper ? TO_OBJECT(thisArg) : thisArg;
- if (%_CallFunction(newThisArg, element, i, array, predicate)) {
+ if (%_Call(predicate, thisArg, element, i, array)) {
return element;
}
}
throw MakeTypeError(kCalledNonCallable, predicate);
}
- var needs_wrapper = false;
- if (IS_NULL(thisArg)) {
- if (%IsSloppyModeFunction(predicate)) thisArg = UNDEFINED;
- } else if (!IS_UNDEFINED(thisArg)) {
- needs_wrapper = SHOULD_CREATE_WRAPPER(predicate, thisArg);
- }
-
for (var i = 0; i < length; i++) {
var element = array[i];
- var newThisArg = needs_wrapper ? TO_OBJECT(thisArg) : thisArg;
- if (%_CallFunction(newThisArg, element, i, array, predicate)) {
+ if (%_Call(predicate, thisArg, element, i, array)) {
return i;
}
}
if (mapping) {
if (!IS_CALLABLE(mapfn)) {
throw MakeTypeError(kCalledNonCallable, mapfn);
- } else if (%IsSloppyModeFunction(mapfn)) {
- if (IS_NULL(receiver)) {
- receiver = UNDEFINED;
- } else if (!IS_UNDEFINED(receiver)) {
- receiver = TO_OBJECT(receiver);
- }
}
}
nextValue = next.value;
if (mapping) {
- mappedValue = %_CallFunction(receiver, nextValue, k, mapfn);
+ mappedValue = %_Call(mapfn, receiver, nextValue, k);
} else {
mappedValue = nextValue;
}
for (k = 0; k < len; ++k) {
nextValue = items[k];
if (mapping) {
- mappedValue = %_CallFunction(receiver, nextValue, k, mapfn);
+ mappedValue = %_Call(mapfn, receiver, nextValue, k);
} else {
mappedValue = nextValue;
}
// ES6 section 22.2.3.28
function TypedArrayToString() {
- return %_CallFunction(this, ArrayToString);
+ return %_Call(ArrayToString, this);
}
function TypedArrayFrom(source, mapfn, thisArg) {
// TODO(littledan): Investigate if there is a receiver which could be
// faster to accumulate on than Array, e.g., a TypedVector.
- var array = %_CallFunction(GlobalArray, source, mapfn, thisArg, ArrayFrom);
+ var array = %_Call(ArrayFrom, GlobalArray, source, mapfn, thisArg);
return ConstructTypedArray(this, array);
}
%FunctionSetLength(TypedArrayFrom, 1);
}
+// Fast support for calls.
+void HOptimizedGraphBuilder::GenerateCall(CallRuntime* call) {
+ DCHECK_LE(2, call->arguments()->length());
+ CHECK_ALIVE(VisitExpressions(call->arguments()));
+ CallTrampolineDescriptor descriptor(isolate());
+ PushArgumentsFromEnvironment(call->arguments()->length() - 1);
+ HValue* trampoline = Add<HConstant>(isolate()->builtins()->Call());
+ HValue* target = Pop();
+ HValue* values[] = {context(), target,
+ Add<HConstant>(call->arguments()->length() - 2)};
+ HInstruction* result = New<HCallWithDescriptor>(
+ trampoline, call->arguments()->length() - 1, descriptor,
+ Vector<HValue*>(values, arraysize(values)));
+ return ast_context()->ReturnInstruction(result, call->id());
+}
+
+
// Fast call for custom callbacks.
void HOptimizedGraphBuilder::GenerateCallFunction(CallRuntime* call) {
// 1 ~ The function to call is not itself an argument to the call.
F(IsRegExp) \
F(IsJSProxy) \
F(IsConstructCall) \
+ F(Call) \
F(CallFunction) \
F(ArgumentsLength) \
F(Arguments) \
}
+void CallTrampolineDescriptor::InitializePlatformSpecific(
+ CallInterfaceDescriptorData* data) {
+ // eax : number of arguments
+ // edi : the target to call
+ Register registers[] = {edi, eax};
+ data->InitializePlatformSpecific(arraysize(registers), registers);
+}
+
+
void RegExpConstructResultDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {ecx, ebx, eax};
Type::FunctionType*
+CallTrampolineDescriptor::BuildCallInterfaceDescriptorFunctionType(
+ Isolate* isolate, int paramater_count) {
+ Zone* zone = isolate->interface_descriptor_zone();
+ Type::FunctionType* function =
+ Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 2, zone);
+ function->InitParameter(0, AnyTagged(zone)); // target
+ function->InitParameter(
+ 1, UntaggedSigned32(zone)); // actual number of arguments
+ return function;
+}
+
+
+Type::FunctionType*
CallFunctionWithFeedbackDescriptor::BuildCallInterfaceDescriptorFunctionType(
Isolate* isolate, int paramater_count) {
Zone* zone = isolate->interface_descriptor_zone();
V(CallFunctionWithFeedback) \
V(CallFunctionWithFeedbackAndVector) \
V(CallConstruct) \
+ V(CallTrampoline) \
V(RegExpConstructResult) \
V(TransitionElementsKind) \
V(AllocateHeapNumber) \
};
+class CallTrampolineDescriptor : public CallInterfaceDescriptor {
+ public:
+ DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(CallTrampolineDescriptor,
+ CallInterfaceDescriptor)
+};
+
+
class CallFunctionDescriptor : public CallInterfaceDescriptor {
public:
DECLARE_DESCRIPTOR(CallFunctionDescriptor, CallInterfaceDescriptor)
}
}
}
- return %_CallFunction(holder, name, val, reviver);
+ return %_Call(reviver, holder, name, val);
}
if (IS_SPEC_OBJECT(value)) {
var toJSON = value.toJSON;
if (IS_CALLABLE(toJSON)) {
- value = %_CallFunction(value, key, toJSON);
+ value = %_Call(toJSON, value, key);
}
}
if (IS_CALLABLE(replacer)) {
- value = %_CallFunction(holder, key, value, replacer);
+ value = %_Call(replacer, holder, key, value);
}
if (IS_STRING(value)) {
return %QuoteJSONString(value);
macro TO_NAME(arg) = (%_ToName(arg));
macro JSON_NUMBER_TO_STRING(arg) = ((%_IsSmi(%IS_VAR(arg)) || arg - arg == 0) ? %_NumberToString(arg) : "null");
macro HAS_OWN_PROPERTY(arg, index) = (%_CallFunction(arg, index, ObjectHasOwnProperty));
-macro SHOULD_CREATE_WRAPPER(functionName, receiver) = (!IS_SPEC_OBJECT(receiver) && %IsSloppyModeFunction(functionName));
macro HAS_INDEX(array, index, is_array) = ((is_array && %_HasFastPackedElements(%IS_VAR(array))) ? (index < array.length) : (index in array));
# Private names.
}
+void CallTrampolineDescriptor::InitializePlatformSpecific(
+ CallInterfaceDescriptorData* data) {
+ // a1: target
+ // a0: number of arguments
+ Register registers[] = {a1, a0};
+ data->InitializePlatformSpecific(arraysize(registers), registers);
+}
+
+
void RegExpConstructResultDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {a2, a1, a0};
}
+void CallTrampolineDescriptor::InitializePlatformSpecific(
+ CallInterfaceDescriptorData* data) {
+ // a1: target
+ // a0: number of arguments
+ Register registers[] = {a1, a0};
+ data->InitializePlatformSpecific(arraysize(registers), registers);
+}
+
+
void RegExpConstructResultDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {a2, a1, a0};
var changeRecord;
try {
- changeRecord = %_CallFunction(UNDEFINED, changeFn);
+ changeRecord = changeFn();
} finally {
ObjectInfoRemovePerformingType(objectInfo, changeType);
}
if (IS_CALLABLE(then)) {
var deferred = %_CallFunction(constructor, PromiseDeferred);
try {
- %_CallFunction(x, deferred.resolve, deferred.reject, then);
+ %_Call(then, x, deferred.resolve, deferred.reject);
} catch(r) {
deferred.reject(r);
}
function DefaultNumber(x) {
var valueOf = x.valueOf;
if (IS_CALLABLE(valueOf)) {
- var v = %_CallFunction(x, valueOf);
+ var v = %_Call(valueOf, x);
if (IS_SYMBOL(v)) throw MakeTypeError(kSymbolToNumber);
if (IS_SIMD_VALUE(x)) throw MakeTypeError(kSimdToNumber);
if (IsPrimitive(v)) return v;
}
var toString = x.toString;
if (IS_CALLABLE(toString)) {
- var s = %_CallFunction(x, toString);
+ var s = %_Call(toString, x);
if (IsPrimitive(s)) return s;
}
throw MakeTypeError(kCannotConvertToPrimitive);
if (IS_SYMBOL(x)) throw MakeTypeError(kSymbolToString);
var toString = x.toString;
if (IS_CALLABLE(toString)) {
- var s = %_CallFunction(x, toString);
+ var s = %_Call(toString, x);
if (IsPrimitive(s)) return s;
}
var valueOf = x.valueOf;
if (IS_CALLABLE(valueOf)) {
- var v = %_CallFunction(x, valueOf);
+ var v = %_Call(valueOf, x);
if (IsPrimitive(v)) return v;
}
}
namespace v8 {
namespace internal {
-// TODO(bmeurer): This is an awful hack resulting from our inability to decide
-// who's responsible for doing the receiver patching. By any means, we really
-// need to kill this runtime function and just do things right instead!!
-RUNTIME_FUNCTION(Runtime_IsSloppyModeFunction) {
- SealHandleScope shs(isolate);
- DCHECK(args.length() == 1);
- CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
- if (!callable->IsJSFunction()) {
- HandleScope scope(isolate);
- Handle<JSFunction> delegate;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, delegate,
- Execution::GetFunctionDelegate(isolate, Handle<JSReceiver>(callable)));
- callable = JSFunction::cast(*delegate);
- }
- JSFunction* function = JSFunction::cast(callable);
- SharedFunctionInfo* shared = function->shared();
- return isolate->heap()->ToBoolean(is_sloppy(shared->language_mode()));
-}
-
-
RUNTIME_FUNCTION(Runtime_FunctionGetName) {
SealHandleScope shs(isolate);
DCHECK(args.length() == 1);
RUNTIME_FUNCTION(Runtime_Call) {
HandleScope scope(isolate);
- DCHECK(args.length() >= 2);
- int argc = args.length() - 2;
- CONVERT_ARG_CHECKED(JSReceiver, fun, argc + 1);
- Object* receiver = args[0];
-
- // If there are too many arguments, allocate argv via malloc.
- const int argv_small_size = 10;
- Handle<Object> argv_small_buffer[argv_small_size];
- base::SmartArrayPointer<Handle<Object> > argv_large_buffer;
- Handle<Object>* argv = argv_small_buffer;
- if (argc > argv_small_size) {
- argv = new Handle<Object>[argc];
- if (argv == NULL) return isolate->StackOverflow();
- argv_large_buffer = base::SmartArrayPointer<Handle<Object> >(argv);
- }
-
+ DCHECK_LE(2, args.length());
+ int const argc = args.length() - 2;
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, target, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
+ ScopedVector<Handle<Object>> argv(argc);
for (int i = 0; i < argc; ++i) {
- argv[i] = Handle<Object>(args[1 + i], isolate);
+ argv[i] = args.at<Object>(2 + i);
}
-
- Handle<JSReceiver> hfun(fun);
- Handle<Object> hreceiver(receiver, isolate);
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result,
- Execution::Call(isolate, hfun, hreceiver, argc, argv, true));
+ Execution::Call(isolate, target, receiver, argc, argv.start(), true));
return *result;
}
}
+// TODO(bmeurer): Kill %_CallFunction ASAP as it is almost never used
+// correctly because of the weird semantics underneath.
RUNTIME_FUNCTION(Runtime_CallFunction) {
- SealHandleScope shs(isolate);
- return __RT_impl_Runtime_Call(args, isolate);
+ HandleScope scope(isolate);
+ DCHECK(args.length() >= 2);
+ int argc = args.length() - 2;
+ CONVERT_ARG_CHECKED(JSReceiver, fun, argc + 1);
+ Object* receiver = args[0];
+
+ // If there are too many arguments, allocate argv via malloc.
+ const int argv_small_size = 10;
+ Handle<Object> argv_small_buffer[argv_small_size];
+ base::SmartArrayPointer<Handle<Object>> argv_large_buffer;
+ Handle<Object>* argv = argv_small_buffer;
+ if (argc > argv_small_size) {
+ argv = new Handle<Object>[argc];
+ if (argv == NULL) return isolate->StackOverflow();
+ argv_large_buffer = base::SmartArrayPointer<Handle<Object>>(argv);
+ }
+
+ for (int i = 0; i < argc; ++i) {
+ argv[i] = Handle<Object>(args[1 + i], isolate);
+ }
+
+ Handle<JSReceiver> hfun(fun);
+ Handle<Object> hreceiver(receiver, isolate);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ Execution::Call(isolate, hfun, hreceiver, argc, argv, true));
+ return *result;
}
#define FOR_EACH_INTRINSIC_FUNCTION(F) \
- F(IsSloppyModeFunction, 1, 1) \
F(FunctionGetName, 1, 1) \
F(FunctionSetName, 2, 1) \
F(FunctionNameShouldPrintAsAnonymous, 1, 1) \
// Compute the string to replace with.
if (IS_CALLABLE(replace)) {
- var receiver = UNDEFINED;
- result += %_CallFunction(receiver, search, start, subject, replace);
+ result += replace(search, start, subject);
} else {
reusableMatchInfo[CAPTURE0] = start;
reusableMatchInfo[CAPTURE1] = end;
override[0] = elem;
override[1] = match_start;
$regexpLastMatchInfoOverride = override;
- var func_result =
- %_CallFunction(UNDEFINED, elem, match_start, subject, replace);
+ var func_result = replace(elem, match_start, subject);
// Overwrite the i'th element in the results with the string we got
// back from the callback function.
res[i] = TO_STRING_INLINE(func_result);
// No captures, only the match, which is always valid.
var s = %_SubString(subject, index, endOfMatch);
// Don't call directly to avoid exposing the built-in global object.
- replacement = %_CallFunction(UNDEFINED, s, index, subject, replace);
+ replacement = replace(s, index, subject);
} else {
var parameters = new InternalArray(m + 2);
for (var j = 0; j < m; j++) {
// was already looked up, and wrap it in another iterable. The
// __proto__ of the new iterable is set to null to avoid any chance
// of modifications to Object.prototype being observable here.
- var iterator = %_CallFunction(iterable, iteratorFn);
+ var iterator = %_Call(iteratorFn, iterable);
var newIterable = {
__proto__: null
};
if (!IS_SPEC_OBJECT(nextItem)) {
throw MakeTypeError(kIteratorValueNotAnObject, nextItem);
}
- %_CallFunction(this, nextItem[0], nextItem[1], adder);
+ %_Call(adder, this, nextItem[0], nextItem[1]);
}
}
}
throw MakeTypeError(kPropertyNotFunction, 'add', this);
}
for (var value of iterable) {
- %_CallFunction(this, value, adder);
+ %_Call(adder, this, value);
}
}
}
}
+void CallTrampolineDescriptor::InitializePlatformSpecific(
+ CallInterfaceDescriptorData* data) {
+ // rax : number of arguments
+ // rdi : the target to call
+ Register registers[] = {rdi, rax};
+ data->InitializePlatformSpecific(arraysize(registers), registers);
+}
+
+
void RegExpConstructResultDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {rcx, rbx, rax};
function WrapInNativeCall(f) {
return function() {
- return %Call(undefined, f);
+ return %Call(f, undefined);
};
}
assertEquals(32, Function.prototype.apply.call(f, o, [17, 15]))
assertSame(o, receiver)
receiver = 333
- assertEquals(42, %Call(o, 11, 31, f))
+ assertEquals(42, %Call(f, o, 11, 31));
assertSame(o, receiver)
receiver = 333
- assertEquals(42, %Call(null, 11, 31, f))
+ assertEquals(42, %Call(f, null, 11, 31));
assertSame(isStrict ? null : global_object, receiver)
receiver = 333
assertEquals(42, %Apply(f, o, [11, 31], 0, 2))
assertEquals(32, Function.prototype.apply.call(ff, {}, [20]))
assertSame(o, receiver)
receiver = 333
- assertEquals(23, %Call({}, 11, ff))
+ assertEquals(23, %Call(ff, {}, 11));
assertSame(o, receiver)
receiver = 333
- assertEquals(23, %Call({}, 11, 3, ff))
+ assertEquals(23, %Call(ff, {}, 11, 3));
assertSame(o, receiver)
receiver = 333
assertEquals(24, %Apply(ff, {}, [12, 13], 0, 1))
assertEquals(42, Function.prototype.apply.call(fff, {}))
assertSame(o, receiver)
receiver = 333
- assertEquals(42, %Call({}, fff))
+ assertEquals(42, %Call(fff, {}));
assertSame(o, receiver)
receiver = 333
- assertEquals(42, %Call({}, 11, 3, fff))
+ assertEquals(42, %Call(fff, {}, 11, 3))
assertSame(o, receiver)
receiver = 333
assertEquals(42, %Apply(fff, {}, [], 0, 0))
assertEquals(32, Function.prototype.apply.call(f, o, [17, 15]))
assertSame(o, receiver)
receiver = 333
- assertEquals(23, %Call(o, 11, 12, f))
+ assertEquals(23, %Call(f, o, 11, 12))
assertSame(o, receiver)
receiver = 333
assertEquals(27, %Apply(f, o, [12, 13, 14], 1, 2))
assertThrows(function(){ ({x: f})["x"](11) }, "myexn")
assertThrows(function(){ Function.prototype.call.call(f, {}, 2) }, "myexn")
assertThrows(function(){ Function.prototype.apply.call(f, {}, [1]) }, "myexn")
- assertThrows(function(){ %Call({}, f) }, "myexn")
- assertThrows(function(){ %Call({}, 1, 2, f) }, "myexn")
+ assertThrows(function(){ %Call(f, {}) }, "myexn")
+ assertThrows(function(){ %Call(f, {}, 1, 2) }, "myexn")
assertThrows(function(){ %Apply({}, f, [], 3, 0) }, "myexn")
assertThrows(function(){ %Apply({}, f, [3, 4], 0, 1) }, "myexn")
assertThrows(function(){ %_CallFunction({}, f) }, "myexn")
assertThrows(function(){ ({x: f})["x"](11) }, "myexn")
assertThrows(function(){ Function.prototype.call.call(f, {}, 2) }, "myexn")
assertThrows(function(){ Function.prototype.apply.call(f, {}, [1]) }, "myexn")
- assertThrows(function(){ %Call({}, f) }, "myexn")
- assertThrows(function(){ %Call({}, 1, 2, f) }, "myexn")
+ assertThrows(function(){ %Call(f, {}) }, "myexn")
+ assertThrows(function(){ %Call(f, {}, 1, 2) }, "myexn")
assertThrows(function(){ %Apply({}, f, [], 3, 0) }, "myexn")
assertThrows(function(){ %Apply({}, f, [3, 4], 0, 1) }, "myexn")
assertThrows(function(){ %_CallFunction({}, f) }, "myexn")
function(f, x, y, o) { return Function.prototype.call.call(f, o, x, y) },
function(f, x, y, o) { return Function.prototype.apply.call(f, o, [x, y]) },
function(f, x, y, o) { return %_CallFunction(o, x, y, f) },
- function(f, x, y, o) { return %Call(o, x, y, f) },
+ function(f, x, y, o) { return %Call(f, o, x, y) },
function(f, x, y, o) { return %Apply(f, o, [null, x, y, null], 1, 2) },
function(f, x, y, o) { return %Apply(f, o, arguments, 2, 2) },
function(f, x, y, o) { if (typeof o == "object") return o.f(x, y) },
`f.bind(undefined)(${generateArguments(argumentCount)})`,
`%_CallFunction(${generateArguments(argumentCount, 'undefined')},
f)`,
- `%Call(${generateArguments(argumentCount, 'undefined')}, f)`,
+ `%Call(f, ${generateArguments(argumentCount, 'undefined')})`,
`%Apply(f, undefined, [${generateArguments(argumentCount)}], 0,
${argumentCount})`,
];
`o.m.apply(o, [${generateArguments(argumentCount)}])`,
`o.m.bind(o)(${generateArguments(argumentCount)})`,
`%_CallFunction(${generateArguments(argumentCount, 'o')}, o.m)`,
- `%Call(${generateArguments(argumentCount, 'o')}, o.m)`,
+ `%Call(o.m, ${generateArguments(argumentCount, 'o')})`,
`%Apply(o.m, o, [${generateArguments(argumentCount)}], 0,
${argumentCount})`,
];