Commit 96e70f6b authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

String check for binary add on x64 and ARM

The checking for strings when performing binary add was missing on x64 and ARM. This is a prerequisite for adding string add in generated code for these two platforms.
Review URL: http://codereview.chromium.org/465028

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3416 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent f95746cb
......@@ -5215,8 +5215,53 @@ static void HandleBinaryOpSlowCases(MacroAssembler* masm,
// We jump to here if something goes wrong (one param is not a number of any
// sort or new-space allocation fails).
__ bind(&slow);
// Push arguments to the stack
__ push(r1);
__ push(r0);
if (Token::ADD == operation) {
// Test for string arguments before calling runtime.
// r1 : first argument
// r0 : second argument
// sp[0] : second argument
// sp[1] : first argument
Label not_strings, not_string1, string1;
__ tst(r1, Operand(kSmiTagMask));
__ b(eq, &not_string1);
__ CompareObjectType(r1, r2, r2, FIRST_NONSTRING_TYPE);
__ b(ge, &not_string1);
// First argument is a a string, test second.
__ tst(r0, Operand(kSmiTagMask));
__ b(eq, &string1);
__ CompareObjectType(r0, r2, r2, FIRST_NONSTRING_TYPE);
__ b(ge, &string1);
// First and second argument are strings.
__ TailCallRuntime(ExternalReference(Runtime::kStringAdd), 2, 1);
// Only first argument is a string.
__ bind(&string1);
__ mov(r0, Operand(2)); // Set number of arguments.
__ InvokeBuiltin(Builtins::STRING_ADD_LEFT, JUMP_JS);
// First argument was not a string, test second.
__ bind(&not_string1);
__ tst(r0, Operand(kSmiTagMask));
__ b(eq, &not_strings);
__ CompareObjectType(r0, r2, r2, FIRST_NONSTRING_TYPE);
__ b(ge, &not_strings);
// Only second argument is a string.
__ b(&not_strings);
__ mov(r0, Operand(2)); // Set number of arguments.
__ InvokeBuiltin(Builtins::STRING_ADD_RIGHT, JUMP_JS);
__ bind(&not_strings);
}
__ mov(r0, Operand(1)); // Set number of arguments.
__ InvokeBuiltin(builtin, JUMP_JS); // Tail call. No return.
......
......@@ -7777,9 +7777,47 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
__ push(rcx);
}
switch (op_) {
case Token::ADD:
case Token::ADD: {
// Test for string arguments before calling runtime.
Label not_strings, both_strings, not_string1, string1;
Condition is_smi;
Result answer;
__ movq(rdx, Operand(rsp, 2 * kPointerSize)); // First argument.
__ movq(rax, Operand(rsp, 1 * kPointerSize)); // Second argument.
is_smi = masm->CheckSmi(rdx);
__ j(is_smi, &not_string1);
__ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rdx);
__ j(above_equal, &not_string1);
// First argument is a a string, test second.
is_smi = masm->CheckSmi(rax);
__ j(is_smi, &string1);
__ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rax);
__ j(above_equal, &string1);
// First and second argument are strings.
Runtime::Function* f = Runtime::FunctionForId(Runtime::kStringAdd);
__ TailCallRuntime(ExternalReference(f), 2, f->result_size);
// Only first argument is a string.
__ bind(&string1);
__ InvokeBuiltin(Builtins::STRING_ADD_LEFT, JUMP_FUNCTION);
// First argument was not a string, test second.
__ bind(&not_string1);
is_smi = masm->CheckSmi(rax);
__ j(is_smi, &not_strings);
__ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rax);
__ j(above_equal, &not_strings);
// Only second argument is a string.
__ InvokeBuiltin(Builtins::STRING_ADD_RIGHT, JUMP_FUNCTION);
__ bind(&not_strings);
// Neither argument is a string.
__ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION);
break;
}
case Token::SUB:
__ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION);
break;
......
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