OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_ARM | 5 #if V8_TARGET_ARCH_ARM |
6 | 6 |
7 #include "src/codegen.h" | 7 #include "src/codegen.h" |
8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 __ mov(r3, r1); | 130 __ mov(r3, r1); |
131 // Run the native code for the Array function called as a normal function. | 131 // Run the native code for the Array function called as a normal function. |
132 // tail call a stub | 132 // tail call a stub |
133 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); | 133 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); |
134 ArrayConstructorStub stub(masm->isolate()); | 134 ArrayConstructorStub stub(masm->isolate()); |
135 __ TailCallStub(&stub); | 135 __ TailCallStub(&stub); |
136 } | 136 } |
137 | 137 |
138 | 138 |
139 // static | 139 // static |
| 140 void Builtins::Generate_NumberConstructor(MacroAssembler* masm) { |
| 141 // ----------- S t a t e ------------- |
| 142 // -- r0 : number of arguments |
| 143 // -- r1 : constructor function |
| 144 // -- lr : return address |
| 145 // -- sp[(argc - n - 1) * 4] : arg[n] (zero based) |
| 146 // -- sp[argc * 4] : receiver |
| 147 // ----------------------------------- |
| 148 |
| 149 // 1. Load the first argument into r0 and get rid of the rest (including the |
| 150 // receiver). |
| 151 Label no_arguments; |
| 152 { |
| 153 __ sub(r0, r0, Operand(1), SetCC); |
| 154 __ b(lo, &no_arguments); |
| 155 __ ldr(r0, MemOperand(sp, r0, LSL, kPointerSizeLog2, PreIndex)); |
| 156 __ Drop(2); |
| 157 } |
| 158 |
| 159 // 2a. Convert the first argument to a number. |
| 160 ToNumberStub stub(masm->isolate()); |
| 161 __ TailCallStub(&stub); |
| 162 |
| 163 // 2b. No arguments, return +0. |
| 164 __ bind(&no_arguments); |
| 165 __ Move(r0, Smi::FromInt(0)); |
| 166 __ Ret(1); |
| 167 } |
| 168 |
| 169 |
| 170 // static |
| 171 void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) { |
| 172 // ----------- S t a t e ------------- |
| 173 // -- r0 : number of arguments |
| 174 // -- r1 : constructor function |
| 175 // -- r3 : new target |
| 176 // -- lr : return address |
| 177 // -- sp[(argc - n - 1) * 4] : arg[n] (zero based) |
| 178 // -- sp[argc * 4] : receiver |
| 179 // ----------------------------------- |
| 180 |
| 181 // 1. Make sure we operate in the context of the called function. |
| 182 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); |
| 183 |
| 184 // 2. Load the first argument into r2 and get rid of the rest (including the |
| 185 // receiver). |
| 186 { |
| 187 Label no_arguments, done; |
| 188 __ sub(r0, r0, Operand(1), SetCC); |
| 189 __ b(lo, &no_arguments); |
| 190 __ ldr(r2, MemOperand(sp, r0, LSL, kPointerSizeLog2, PreIndex)); |
| 191 __ Drop(2); |
| 192 __ b(&done); |
| 193 __ bind(&no_arguments); |
| 194 __ Move(r2, Smi::FromInt(0)); |
| 195 __ Drop(1); |
| 196 __ bind(&done); |
| 197 } |
| 198 |
| 199 // 3. Make sure r2 is a number. |
| 200 { |
| 201 Label done_convert; |
| 202 __ JumpIfSmi(r2, &done_convert); |
| 203 __ CompareObjectType(r2, r4, r4, HEAP_NUMBER_TYPE); |
| 204 __ b(eq, &done_convert); |
| 205 { |
| 206 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 207 __ Push(r1, r3); |
| 208 __ Move(r0, r2); |
| 209 ToNumberStub stub(masm->isolate()); |
| 210 __ CallStub(&stub); |
| 211 __ Move(r2, r0); |
| 212 __ Pop(r1, r3); |
| 213 } |
| 214 __ bind(&done_convert); |
| 215 } |
| 216 |
| 217 // 4. Check if new target and constructor differ. |
| 218 Label new_object; |
| 219 __ cmp(r1, r3); |
| 220 __ b(ne, &new_object); |
| 221 |
| 222 // 5. Allocate a JSValue wrapper for the number. |
| 223 __ AllocateJSValue(r0, r1, r2, r4, r5, &new_object); |
| 224 __ Ret(); |
| 225 |
| 226 // 6. Fallback to the runtime to create new object. |
| 227 __ bind(&new_object); |
| 228 { |
| 229 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 230 __ Push(r2, r1, r3); // first argument, constructor, new target |
| 231 __ CallRuntime(Runtime::kNewObject); |
| 232 __ Pop(r2); |
| 233 } |
| 234 __ str(r2, FieldMemOperand(r0, JSValue::kValueOffset)); |
| 235 __ Ret(); |
| 236 } |
| 237 |
| 238 |
| 239 // static |
140 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { | 240 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { |
141 // ----------- S t a t e ------------- | 241 // ----------- S t a t e ------------- |
142 // -- r0 : number of arguments | 242 // -- r0 : number of arguments |
143 // -- r1 : constructor function | 243 // -- r1 : constructor function |
144 // -- lr : return address | 244 // -- lr : return address |
145 // -- sp[(argc - n - 1) * 4] : arg[n] (zero based) | 245 // -- sp[(argc - n - 1) * 4] : arg[n] (zero based) |
146 // -- sp[argc * 4] : receiver | 246 // -- sp[argc * 4] : receiver |
147 // ----------------------------------- | 247 // ----------------------------------- |
148 | 248 |
149 // 1. Load the first argument into r0 and get rid of the rest (including the | 249 // 1. Load the first argument into r0 and get rid of the rest (including the |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { | 295 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { |
196 // ----------- S t a t e ------------- | 296 // ----------- S t a t e ------------- |
197 // -- r0 : number of arguments | 297 // -- r0 : number of arguments |
198 // -- r1 : constructor function | 298 // -- r1 : constructor function |
199 // -- r3 : new target | 299 // -- r3 : new target |
200 // -- lr : return address | 300 // -- lr : return address |
201 // -- sp[(argc - n - 1) * 4] : arg[n] (zero based) | 301 // -- sp[(argc - n - 1) * 4] : arg[n] (zero based) |
202 // -- sp[argc * 4] : receiver | 302 // -- sp[argc * 4] : receiver |
203 // ----------------------------------- | 303 // ----------------------------------- |
204 | 304 |
205 // 1. Load the first argument into r2 and get rid of the rest (including the | 305 // 1. Make sure we operate in the context of the called function. |
| 306 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); |
| 307 |
| 308 // 2. Load the first argument into r2 and get rid of the rest (including the |
206 // receiver). | 309 // receiver). |
207 { | 310 { |
208 Label no_arguments, done; | 311 Label no_arguments, done; |
209 __ sub(r0, r0, Operand(1), SetCC); | 312 __ sub(r0, r0, Operand(1), SetCC); |
210 __ b(lo, &no_arguments); | 313 __ b(lo, &no_arguments); |
211 __ ldr(r2, MemOperand(sp, r0, LSL, kPointerSizeLog2, PreIndex)); | 314 __ ldr(r2, MemOperand(sp, r0, LSL, kPointerSizeLog2, PreIndex)); |
212 __ Drop(2); | 315 __ Drop(2); |
213 __ b(&done); | 316 __ b(&done); |
214 __ bind(&no_arguments); | 317 __ bind(&no_arguments); |
215 __ LoadRoot(r2, Heap::kempty_stringRootIndex); | 318 __ LoadRoot(r2, Heap::kempty_stringRootIndex); |
216 __ Drop(1); | 319 __ Drop(1); |
217 __ bind(&done); | 320 __ bind(&done); |
218 } | 321 } |
219 | 322 |
220 // 2. Make sure r2 is a string. | 323 // 3. Make sure r2 is a string. |
221 { | 324 { |
222 Label convert, done_convert; | 325 Label convert, done_convert; |
223 __ JumpIfSmi(r2, &convert); | 326 __ JumpIfSmi(r2, &convert); |
224 __ CompareObjectType(r2, r4, r4, FIRST_NONSTRING_TYPE); | 327 __ CompareObjectType(r2, r4, r4, FIRST_NONSTRING_TYPE); |
225 __ b(lo, &done_convert); | 328 __ b(lo, &done_convert); |
226 __ bind(&convert); | 329 __ bind(&convert); |
227 { | 330 { |
228 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 331 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
229 ToStringStub stub(masm->isolate()); | 332 ToStringStub stub(masm->isolate()); |
230 __ Push(r1, r3); | 333 __ Push(r1, r3); |
231 __ Move(r0, r2); | 334 __ Move(r0, r2); |
232 __ CallStub(&stub); | 335 __ CallStub(&stub); |
233 __ Move(r2, r0); | 336 __ Move(r2, r0); |
234 __ Pop(r1, r3); | 337 __ Pop(r1, r3); |
235 } | 338 } |
236 __ bind(&done_convert); | 339 __ bind(&done_convert); |
237 } | 340 } |
238 | 341 |
239 // 3. Check if new target and constructor differ. | 342 // 4. Check if new target and constructor differ. |
240 Label new_object; | 343 Label new_object; |
241 __ cmp(r1, r3); | 344 __ cmp(r1, r3); |
242 __ b(ne, &new_object); | 345 __ b(ne, &new_object); |
243 | 346 |
244 // 4. Allocate a JSValue wrapper for the string. | 347 // 5. Allocate a JSValue wrapper for the string. |
245 { | 348 __ AllocateJSValue(r0, r1, r2, r4, r5, &new_object); |
246 // ----------- S t a t e ------------- | 349 __ Ret(); |
247 // -- r2 : the first argument | |
248 // -- r1 : constructor function | |
249 // -- r3 : new target | |
250 // -- lr : return address | |
251 // ----------------------------------- | |
252 __ Allocate(JSValue::kSize, r0, r4, r5, &new_object, TAG_OBJECT); | |
253 | 350 |
254 // Initialize the JSValue in r0. | 351 // 6. Fallback to the runtime to create new object. |
255 __ LoadGlobalFunctionInitialMap(r1, r3, r4); | |
256 __ str(r3, FieldMemOperand(r0, HeapObject::kMapOffset)); | |
257 __ LoadRoot(r3, Heap::kEmptyFixedArrayRootIndex); | |
258 __ str(r3, FieldMemOperand(r0, JSObject::kPropertiesOffset)); | |
259 __ str(r3, FieldMemOperand(r0, JSObject::kElementsOffset)); | |
260 __ str(r2, FieldMemOperand(r0, JSValue::kValueOffset)); | |
261 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); | |
262 __ Ret(); | |
263 } | |
264 | |
265 // 5. Fallback to the runtime to create new object. | |
266 __ bind(&new_object); | 352 __ bind(&new_object); |
267 { | 353 { |
268 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 354 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
269 __ Push(r2, r1, r3); // first argument, constructor, new target | 355 __ Push(r2, r1, r3); // first argument, constructor, new target |
270 __ CallRuntime(Runtime::kNewObject); | 356 __ CallRuntime(Runtime::kNewObject); |
271 __ Pop(r2); | 357 __ Pop(r2); |
272 } | 358 } |
273 __ str(r2, FieldMemOperand(r0, JSValue::kValueOffset)); | 359 __ str(r2, FieldMemOperand(r0, JSValue::kValueOffset)); |
274 __ Ret(); | 360 __ Ret(); |
275 } | 361 } |
(...skipping 2068 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2344 } | 2430 } |
2345 } | 2431 } |
2346 | 2432 |
2347 | 2433 |
2348 #undef __ | 2434 #undef __ |
2349 | 2435 |
2350 } // namespace internal | 2436 } // namespace internal |
2351 } // namespace v8 | 2437 } // namespace v8 |
2352 | 2438 |
2353 #endif // V8_TARGET_ARCH_ARM | 2439 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |