| Index: src/arm/full-codegen-arm.cc
|
| diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
|
| index 1d26aba6e2da87dd5913eb74c9972599cc264abb..ea5a8f2a8370397f1af3546e21536395b3e5acfc 100644
|
| --- a/src/arm/full-codegen-arm.cc
|
| +++ b/src/arm/full-codegen-arm.cc
|
| @@ -1104,13 +1104,13 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var,
|
|
|
| void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
|
| Comment cmnt(masm_, "[ RegExpLiteral");
|
| - Label done;
|
| + Label materialized;
|
| // Registers will be used as follows:
|
| // r4 = JS function, literals array
|
| // r3 = literal index
|
| // r2 = RegExp pattern
|
| // r1 = RegExp flags
|
| - // r0 = temp + return value (RegExp literal)
|
| + // r0 = temp + materialized value (RegExp literal)
|
| __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
|
| __ ldr(r4, FieldMemOperand(r0, JSFunction::kLiteralsOffset));
|
| int literal_offset =
|
| @@ -1118,13 +1118,24 @@ void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
|
| __ ldr(r0, FieldMemOperand(r4, literal_offset));
|
| __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
|
| __ cmp(r0, ip);
|
| - __ b(ne, &done);
|
| + __ b(ne, &materialized);
|
| __ mov(r3, Operand(Smi::FromInt(expr->literal_index())));
|
| __ mov(r2, Operand(expr->pattern()));
|
| __ mov(r1, Operand(expr->flags()));
|
| __ Push(r4, r3, r2, r1);
|
| __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
|
| - __ bind(&done);
|
| + __ bind(&materialized);
|
| + int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
|
| + __ push(r0);
|
| + __ mov(r0, Operand(Smi::FromInt(size)));
|
| + __ push(r0);
|
| + __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
|
| + // After this, registers are used as follows:
|
| + // r0: Newly allocated regexp.
|
| + // r1: Materialized regexp
|
| + // r2: temp.
|
| + __ pop(r1);
|
| + __ CopyFields(r0, r1, r2.bit(), size / kPointerSize);
|
| Apply(context_, r0);
|
| }
|
|
|
| @@ -2566,6 +2577,47 @@ void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| +void FullCodeGenerator::EmitIsRegExpEquivalent(ZoneList<Expression*>* args) {
|
| + ASSERT_EQ(2, args->length());
|
| +
|
| + Register right = r0;
|
| + Register left = r1;
|
| + Register tmp = r2;
|
| + Register tmp2 = r3;
|
| +
|
| + VisitForValue(args->at(0), kStack);
|
| + VisitForValue(args->at(1), kAccumulator);
|
| + __ pop(left);
|
| +
|
| + Label done, fail, ok;
|
| + __ cmp(left, Operand(right));
|
| + __ b(eq, &ok);
|
| + // Fail if either is a non-HeapObject.
|
| + __ and_(tmp, left, Operand(right));
|
| + __ tst(tmp, Operand(kSmiTagMask));
|
| + __ b(eq, &fail);
|
| + __ ldr(tmp, FieldMemOperand(left, HeapObject::kMapOffset));
|
| + __ ldrb(tmp2, FieldMemOperand(tmp, Map::kInstanceTypeOffset));
|
| + __ cmp(tmp2, Operand(JS_REGEXP_TYPE));
|
| + __ b(ne, &fail);
|
| + __ ldr(tmp2, FieldMemOperand(right, HeapObject::kMapOffset));
|
| + __ cmp(tmp, Operand(tmp2));
|
| + __ b(ne, &fail);
|
| + __ ldr(tmp, FieldMemOperand(left, JSRegExp::kDataOffset));
|
| + __ ldr(tmp2, FieldMemOperand(right, JSRegExp::kDataOffset));
|
| + __ cmp(tmp, tmp2);
|
| + __ b(eq, &ok);
|
| + __ bind(&fail);
|
| + __ LoadRoot(r0, Heap::kFalseValueRootIndex);
|
| + __ jmp(&done);
|
| + __ bind(&ok);
|
| + __ LoadRoot(r0, Heap::kTrueValueRootIndex);
|
| + __ bind(&done);
|
| +
|
| + Apply(context_, r0);
|
| +}
|
| +
|
| +
|
| void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
| Handle<String> name = expr->name();
|
| if (name->length() > 0 && name->Get(0) == '_') {
|
|
|