Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 the V8 project authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "src/builtins/builtins-arguments.h" | |
| 6 #include "src/builtins/builtins-utils.h" | |
| 7 #include "src/builtins/builtins.h" | |
| 8 #include "src/code-factory.h" | |
| 9 #include "src/code-stub-assembler.h" | |
| 10 #include "src/interface-descriptors.h" | |
| 11 | |
| 12 namespace v8 { | |
| 13 namespace internal { | |
| 14 | |
| 15 typedef compiler::Node Node; | |
| 16 | |
| 17 std::tuple<Node*, Node*, Node*> | |
| 18 ArgumentsBuiltinsAssembler::GetArgumentsFrameAndCount(Node* function, | |
| 19 ParameterMode mode) { | |
| 20 CSA_ASSERT(this, HasInstanceType(function, JS_FUNCTION_TYPE)); | |
| 21 | |
| 22 Variable frame_ptr(this, MachineType::PointerRepresentation()); | |
| 23 frame_ptr.Bind(LoadParentFramePointer()); | |
| 24 CSA_ASSERT(this, | |
| 25 WordEqual(function, | |
| 26 LoadBufferObject(frame_ptr.value(), | |
| 27 StandardFrameConstants::kFunctionOffset, | |
| 28 MachineType::Pointer()))); | |
| 29 Variable argument_count(this, mode == SMI_PARAMETERS | |
|
Igor Sheludko
2017/02/06 20:17:02
Please introduce CSA::ParameterRepresentation(Para
danno
2017/02/07 15:30:20
Done.
| |
| 30 ? MachineRepresentation::kTagged | |
| 31 : MachineType::PointerRepresentation()); | |
| 32 Variable formal_parameter_count( | |
| 33 this, mode == SMI_PARAMETERS ? MachineRepresentation::kTagged | |
|
Igor Sheludko
2017/02/06 20:17:03
Same here.
danno
2017/02/07 15:30:20
Done.
| |
| 34 : MachineType::PointerRepresentation()); | |
| 35 VariableList list({&frame_ptr, &formal_parameter_count, &argument_count}, | |
| 36 zone()); | |
| 37 Label no_arguments_adaptor(this), done_argument_count(this, list); | |
| 38 | |
| 39 // Determine the number of passed parameters, which is either the count stored | |
| 40 // in an arguments adapter frame or fetched from the shared function info. | |
| 41 Node* frame_ptr_above = LoadBufferObject( | |
| 42 frame_ptr.value(), StandardFrameConstants::kCallerFPOffset, | |
| 43 MachineType::Pointer()); | |
| 44 Node* marker_or_function = LoadBufferObject( | |
| 45 frame_ptr_above, CommonFrameConstants::kContextOrFrameTypeOffset); | |
| 46 GotoIf(SmiNotEqual(marker_or_function, | |
| 47 SmiConstant(StackFrame::ARGUMENTS_ADAPTOR)), | |
| 48 &no_arguments_adaptor); | |
| 49 Comment("Has ARGUMENTS_ADAPTOR"); | |
| 50 Node* adapted_parameter_count = LoadBufferObject( | |
| 51 frame_ptr_above, ArgumentsAdaptorFrameConstants::kLengthOffset); | |
| 52 frame_ptr.Bind(frame_ptr_above); | |
| 53 argument_count.Bind(TaggedToParameter(adapted_parameter_count, mode)); | |
| 54 Node* shared = | |
| 55 LoadObjectField(function, JSFunction::kSharedFunctionInfoOffset); | |
| 56 Node* parameter_count = LoadSharedFunctionInfoSpecialField( | |
| 57 shared, SharedFunctionInfo::kFormalParameterCountOffset, mode); | |
| 58 formal_parameter_count.Bind(parameter_count); | |
|
Igor Sheludko
2017/02/06 20:17:02
It looks like the formal_parameter_count computati
danno
2017/02/07 15:30:20
Done.
| |
| 59 Goto(&done_argument_count); | |
| 60 | |
| 61 Bind(&no_arguments_adaptor); | |
| 62 Comment("No ARGUMENTS_ADAPTOR"); | |
| 63 shared = LoadObjectField(function, JSFunction::kSharedFunctionInfoOffset); | |
| 64 parameter_count = LoadSharedFunctionInfoSpecialField( | |
| 65 shared, SharedFunctionInfo::kFormalParameterCountOffset, mode); | |
| 66 formal_parameter_count.Bind(parameter_count); | |
| 67 argument_count.Bind(parameter_count); | |
|
Igor Sheludko
2017/02/06 20:17:03
And if you also bind this above then the no-adapte
danno
2017/02/07 15:30:20
Done.
| |
| 68 Goto(&done_argument_count); | |
| 69 | |
| 70 Bind(&done_argument_count); | |
| 71 return std::tuple<Node*, Node*, Node*>(frame_ptr.value(), | |
| 72 argument_count.value(), | |
| 73 formal_parameter_count.value()); | |
| 74 } | |
| 75 | |
| 76 std::tuple<Node*, Node*, Node*> | |
| 77 ArgumentsBuiltinsAssembler::AllocateArgumentsObject(Node* map, | |
| 78 Node* arguments_count, | |
| 79 Node* parameter_map_count, | |
| 80 ParameterMode mode, | |
| 81 int base_size) { | |
| 82 // Allocate the parameter object (either a Rest parameter object, a strict | |
| 83 // argument object or a sloppy arguments object) and the elements/mapped | |
| 84 // arguments together. | |
| 85 int elements_offset = base_size; | |
| 86 Node* element_count = arguments_count; | |
| 87 if (parameter_map_count != nullptr) { | |
| 88 base_size += FixedArray::kHeaderSize; | |
| 89 element_count = IntPtrOrSmiAdd(element_count, parameter_map_count, mode); | |
| 90 } | |
| 91 bool empty = IsIntPtrOrSmiConstantZero(arguments_count); | |
|
Igor Sheludko
2017/02/06 20:17:02
DCHECK_IMPLIES(empty, parameter_map_count == nullp
danno
2017/02/07 15:30:20
Done.
| |
| 92 Node* size = | |
| 93 empty ? IntPtrConstant(base_size) | |
| 94 : ElementOffsetFromIndex(element_count, FAST_ELEMENTS, mode, | |
| 95 base_size + FixedArray::kHeaderSize); | |
| 96 Node* result = Allocate(size); | |
| 97 Comment("Initialize arguments object"); | |
| 98 StoreMapNoWriteBarrier(result, map); | |
| 99 Node* empty_fixed_array = LoadRoot(Heap::kEmptyFixedArrayRootIndex); | |
| 100 StoreObjectField(result, JSArray::kPropertiesOffset, empty_fixed_array); | |
| 101 Node* smi_arguments_count = ParameterToTagged(arguments_count, mode); | |
| 102 StoreObjectFieldNoWriteBarrier(result, JSArray::kLengthOffset, | |
| 103 smi_arguments_count); | |
| 104 Node* arguments = nullptr; | |
| 105 if (!empty) { | |
| 106 arguments = InnerAllocate(result, elements_offset); | |
| 107 StoreObjectFieldNoWriteBarrier(arguments, FixedArray::kLengthOffset, | |
| 108 smi_arguments_count); | |
| 109 Node* fixed_array_map = LoadRoot(Heap::kFixedArrayMapRootIndex); | |
| 110 StoreMapNoWriteBarrier(arguments, fixed_array_map); | |
| 111 } | |
| 112 Node* parameter_map = nullptr; | |
| 113 if (parameter_map_count != nullptr) { | |
| 114 Node* parameter_map_offset = ElementOffsetFromIndex( | |
| 115 arguments_count, FAST_ELEMENTS, mode, FixedArray::kHeaderSize); | |
| 116 parameter_map = InnerAllocate(arguments, parameter_map_offset); | |
| 117 StoreObjectFieldNoWriteBarrier(result, JSArray::kElementsOffset, | |
| 118 parameter_map); | |
| 119 Node* sloppy_elements_map = | |
| 120 LoadRoot(Heap::kSloppyArgumentsElementsMapRootIndex); | |
| 121 StoreMapNoWriteBarrier(parameter_map, sloppy_elements_map); | |
| 122 parameter_map_count = ParameterToTagged(parameter_map_count, mode); | |
| 123 StoreObjectFieldNoWriteBarrier(parameter_map, FixedArray::kLengthOffset, | |
| 124 parameter_map_count); | |
| 125 } else { | |
| 126 if (empty) { | |
| 127 StoreObjectFieldNoWriteBarrier(result, JSArray::kElementsOffset, | |
| 128 empty_fixed_array); | |
| 129 } else { | |
| 130 StoreObjectFieldNoWriteBarrier(result, JSArray::kElementsOffset, | |
| 131 arguments); | |
| 132 } | |
| 133 } | |
| 134 return std::tuple<Node*, Node*, Node*>(result, arguments, parameter_map); | |
| 135 } | |
| 136 | |
| 137 Node* ArgumentsBuiltinsAssembler::ConstructParametersObjectFromArgs( | |
| 138 Node* map, Node* frame_ptr, Node* arg_count, Node* first_arg, | |
| 139 Node* rest_count, ParameterMode param_mode, int base_size) { | |
| 140 // Allocate the parameter object (either a Rest parameter object, a strict | |
| 141 // argument object or a sloppy arguments object) and the elements together and | |
| 142 // fill in the contents with the arguments above |formal_parameter_count|. | |
| 143 Node* result; | |
| 144 Node* elements; | |
| 145 Node* unused; | |
| 146 std::tie(result, elements, unused) = | |
| 147 AllocateArgumentsObject(map, rest_count, nullptr, param_mode, base_size); | |
| 148 DCHECK(unused == nullptr); | |
| 149 CodeStubArguments arguments(this, arg_count, frame_ptr, param_mode); | |
| 150 Variable offset(this, MachineType::PointerRepresentation()); | |
| 151 offset.Bind(IntPtrConstant(FixedArrayBase::kHeaderSize - kHeapObjectTag)); | |
| 152 VariableList list({&offset}, zone()); | |
| 153 arguments.ForEach(list, | |
| 154 [this, elements, &offset](Node* arg) { | |
| 155 StoreNoWriteBarrier(MachineRepresentation::kTagged, | |
| 156 elements, offset.value(), arg); | |
| 157 Increment(offset, kPointerSize); | |
| 158 }, | |
| 159 first_arg, nullptr, param_mode); | |
| 160 return result; | |
| 161 } | |
| 162 | |
| 163 Node* ArgumentsBuiltinsAssembler::EmitFastNewRestParameter(Node* context, | |
| 164 Node* function) { | |
| 165 Node* frame_ptr; | |
| 166 Node* argument_count; | |
| 167 Node* formal_parameter_count; | |
| 168 | |
| 169 ParameterMode mode = OptimalParameterMode(); | |
| 170 Node* zero = IntPtrOrSmiConstant(0, mode); | |
| 171 | |
| 172 std::tie(frame_ptr, argument_count, formal_parameter_count) = | |
| 173 GetArgumentsFrameAndCount(function, mode); | |
| 174 | |
| 175 Variable result(this, MachineRepresentation::kTagged); | |
| 176 Label no_rest_parameters(this), runtime(this, Label::kDeferred), | |
| 177 done(this, &result); | |
| 178 | |
| 179 Node* rest_count = | |
| 180 IntPtrOrSmiSub(argument_count, formal_parameter_count, mode); | |
| 181 Node* const native_context = LoadNativeContext(context); | |
| 182 Node* const array_map = LoadJSArrayElementsMap(FAST_ELEMENTS, native_context); | |
| 183 GotoIf(IntPtrOrSmiLessThanOrEqual(rest_count, zero, mode), | |
| 184 &no_rest_parameters); | |
| 185 | |
| 186 GotoIfFixedArraySizeDoesntFitInNewSpace( | |
| 187 rest_count, &runtime, JSArray::kSize + FixedArray::kHeaderSize, mode); | |
| 188 | |
| 189 // Allocate the Rest JSArray and the elements together and fill in the | |
| 190 // contents with the arguments above |formal_parameter_count|. | |
| 191 result.Bind(ConstructParametersObjectFromArgs( | |
| 192 array_map, frame_ptr, argument_count, formal_parameter_count, rest_count, | |
| 193 mode, JSArray::kSize)); | |
| 194 Goto(&done); | |
| 195 | |
| 196 Bind(&no_rest_parameters); | |
| 197 { | |
| 198 Node* arguments; | |
| 199 Node* elements; | |
| 200 Node* unused; | |
| 201 std::tie(arguments, elements, unused) = | |
| 202 AllocateArgumentsObject(array_map, zero, nullptr, mode, JSArray::kSize); | |
| 203 result.Bind(arguments); | |
| 204 Goto(&done); | |
| 205 } | |
| 206 | |
| 207 Bind(&runtime); | |
| 208 { | |
| 209 result.Bind(CallRuntime(Runtime::kNewRestParameter, context, function)); | |
| 210 Goto(&done); | |
| 211 } | |
| 212 | |
| 213 Bind(&done); | |
| 214 return result.value(); | |
| 215 } | |
| 216 | |
| 217 TF_BUILTIN(FastNewRestParameter, ArgumentsBuiltinsAssembler) { | |
| 218 Node* function = Parameter(FastNewStrictArgumentsDescriptor::kFunction); | |
| 219 Node* context = Parameter(FastNewStrictArgumentsDescriptor::kContext); | |
| 220 Return(EmitFastNewRestParameter(context, function)); | |
| 221 } | |
| 222 | |
| 223 Node* ArgumentsBuiltinsAssembler::EmitFastNewStrictArguments(Node* context, | |
| 224 Node* function) { | |
| 225 Variable result(this, MachineRepresentation::kTagged); | |
| 226 Label done(this, &result), empty(this), runtime(this, Label::kDeferred); | |
| 227 | |
| 228 Node* frame_ptr; | |
| 229 Node* argument_count; | |
| 230 Node* formal_parameter_count; | |
| 231 | |
| 232 ParameterMode mode = OptimalParameterMode(); | |
| 233 Node* zero = IntPtrOrSmiConstant(0, mode); | |
| 234 | |
| 235 std::tie(frame_ptr, argument_count, formal_parameter_count) = | |
| 236 GetArgumentsFrameAndCount(function, mode); | |
| 237 | |
| 238 GotoIfFixedArraySizeDoesntFitInNewSpace( | |
| 239 argument_count, &runtime, | |
| 240 JSStrictArgumentsObject::kSize + FixedArray::kHeaderSize, mode); | |
| 241 | |
| 242 Node* const native_context = LoadNativeContext(context); | |
| 243 Node* const map = | |
| 244 LoadContextElement(native_context, Context::STRICT_ARGUMENTS_MAP_INDEX); | |
| 245 GotoIf(WordEqual(argument_count, zero), &empty); | |
| 246 | |
| 247 result.Bind(ConstructParametersObjectFromArgs( | |
| 248 map, frame_ptr, argument_count, zero, argument_count, mode, | |
| 249 JSStrictArgumentsObject::kSize)); | |
| 250 Goto(&done); | |
| 251 | |
| 252 Bind(&empty); | |
| 253 { | |
| 254 Node* arguments; | |
| 255 Node* elements; | |
| 256 Node* unused; | |
| 257 std::tie(arguments, elements, unused) = AllocateArgumentsObject( | |
| 258 map, zero, nullptr, mode, JSStrictArgumentsObject::kSize); | |
| 259 result.Bind(arguments); | |
| 260 Goto(&done); | |
| 261 } | |
| 262 | |
| 263 Bind(&runtime); | |
| 264 { | |
| 265 result.Bind(CallRuntime(Runtime::kNewStrictArguments, context, function)); | |
| 266 Goto(&done); | |
| 267 } | |
| 268 | |
| 269 Bind(&done); | |
| 270 return result.value(); | |
| 271 } | |
| 272 | |
| 273 TF_BUILTIN(FastNewStrictArguments, ArgumentsBuiltinsAssembler) { | |
| 274 Node* function = Parameter(FastNewStrictArgumentsDescriptor::kFunction); | |
| 275 Node* context = Parameter(FastNewStrictArgumentsDescriptor::kContext); | |
| 276 Return(EmitFastNewStrictArguments(context, function)); | |
| 277 } | |
| 278 | |
| 279 Node* ArgumentsBuiltinsAssembler::EmitFastNewSloppyArguments(Node* context, | |
| 280 Node* function) { | |
| 281 Node* frame_ptr; | |
| 282 Node* argument_count; | |
| 283 Node* formal_parameter_count; | |
| 284 Variable result(this, MachineRepresentation::kTagged); | |
| 285 | |
| 286 ParameterMode mode = OptimalParameterMode(); | |
| 287 Node* zero = IntPtrOrSmiConstant(0, mode); | |
| 288 | |
| 289 Label done(this, &result), empty(this), no_parameters(this), | |
| 290 runtime(this, Label::kDeferred); | |
| 291 | |
| 292 std::tie(frame_ptr, argument_count, formal_parameter_count) = | |
| 293 GetArgumentsFrameAndCount(function, mode); | |
| 294 | |
| 295 GotoIf(WordEqual(argument_count, zero), &empty); | |
| 296 | |
| 297 GotoIf(WordEqual(formal_parameter_count, zero), &no_parameters); | |
| 298 | |
| 299 { | |
| 300 Comment("Mapped parameter JSSloppyArgumentsObject"); | |
| 301 | |
| 302 Node* mapped_count = | |
| 303 IntPtrOrSmiMin(argument_count, formal_parameter_count, mode); | |
| 304 | |
| 305 Node* parameter_map_size = | |
| 306 IntPtrOrSmiAdd(mapped_count, IntPtrOrSmiConstant(2, mode), mode); | |
| 307 | |
| 308 // Verify that the overall allocation will fit in new space. | |
| 309 Node* elements_allocated = | |
| 310 IntPtrOrSmiAdd(argument_count, parameter_map_size, mode); | |
| 311 GotoIfFixedArraySizeDoesntFitInNewSpace( | |
| 312 elements_allocated, &runtime, | |
| 313 JSSloppyArgumentsObject::kSize + FixedArray::kHeaderSize * 2, mode); | |
| 314 | |
| 315 Node* const native_context = LoadNativeContext(context); | |
| 316 Node* const map = LoadContextElement( | |
| 317 native_context, Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX); | |
| 318 Node* argument_object; | |
| 319 Node* elements; | |
| 320 Node* map_array; | |
| 321 std::tie(argument_object, elements, map_array) = | |
| 322 AllocateArgumentsObject(map, argument_count, parameter_map_size, mode, | |
| 323 JSSloppyArgumentsObject::kSize); | |
| 324 StoreObjectFieldNoWriteBarrier( | |
| 325 argument_object, JSSloppyArgumentsObject::kCalleeOffset, function); | |
| 326 StoreFixedArrayElement(map_array, 0, context, SKIP_WRITE_BARRIER); | |
| 327 StoreFixedArrayElement(map_array, 1, elements, SKIP_WRITE_BARRIER); | |
| 328 | |
| 329 Comment("Fill in non-mapped parameters"); | |
| 330 Node* argument_offset = | |
| 331 ElementOffsetFromIndex(argument_count, FAST_ELEMENTS, mode, | |
| 332 FixedArray::kHeaderSize - kHeapObjectTag); | |
| 333 Node* mapped_offset = | |
| 334 ElementOffsetFromIndex(mapped_count, FAST_ELEMENTS, mode, | |
| 335 FixedArray::kHeaderSize - kHeapObjectTag); | |
| 336 CodeStubArguments arguments(this, argument_count, frame_ptr, mode); | |
| 337 Variable current_argument(this, MachineType::PointerRepresentation()); | |
| 338 current_argument.Bind(arguments.AtIndexPtr(argument_count, mode)); | |
| 339 VariableList var_list1({¤t_argument}, zone()); | |
| 340 mapped_offset = BuildFastLoop( | |
| 341 var_list1, MachineType::PointerRepresentation(), argument_offset, | |
| 342 mapped_offset, | |
| 343 [this, elements, ¤t_argument](Node* offset) { | |
| 344 Increment(current_argument, kPointerSize); | |
| 345 Node* arg = LoadBufferObject(current_argument.value(), 0); | |
| 346 StoreNoWriteBarrier(MachineRepresentation::kTagged, elements, offset, | |
| 347 arg); | |
| 348 }, | |
| 349 -kPointerSize); | |
| 350 | |
| 351 // Copy the parameter slots and the holes in the arguments. | |
| 352 // We need to fill in mapped_count slots. They index the context, | |
| 353 // where parameters are stored in reverse order, at | |
| 354 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+argument_count-1 | |
| 355 // The mapped parameter thus need to get indices | |
| 356 // MIN_CONTEXT_SLOTS+parameter_count-1 .. | |
| 357 // MIN_CONTEXT_SLOTS+argument_count-mapped_count | |
| 358 // We loop from right to left. | |
| 359 Comment("Fill in mapped parameters"); | |
| 360 Variable context_index(this, OptimalParameterRepresentation()); | |
| 361 context_index.Bind(IntPtrOrSmiSub( | |
| 362 IntPtrOrSmiAdd(IntPtrOrSmiConstant(Context::MIN_CONTEXT_SLOTS, mode), | |
| 363 formal_parameter_count, mode), | |
| 364 mapped_count, mode)); | |
| 365 Node* the_hole = TheHoleConstant(); | |
| 366 VariableList var_list2({&context_index}, zone()); | |
| 367 const int kParameterMapHeaderSize = | |
| 368 FixedArray::kHeaderSize + 2 * kPointerSize; | |
| 369 Node* adjusted_map_array = IntPtrAdd( | |
| 370 BitcastTaggedToWord(map_array), | |
| 371 IntPtrConstant(kParameterMapHeaderSize - FixedArray::kHeaderSize)); | |
| 372 Node* zero_offset = ElementOffsetFromIndex( | |
| 373 zero, FAST_ELEMENTS, mode, FixedArray::kHeaderSize - kHeapObjectTag); | |
| 374 BuildFastLoop(var_list2, MachineType::PointerRepresentation(), | |
| 375 mapped_offset, zero_offset, | |
| 376 [this, the_hole, elements, adjusted_map_array, &context_index, | |
| 377 mode](Node* offset) { | |
| 378 StoreNoWriteBarrier(MachineRepresentation::kTagged, | |
| 379 elements, offset, the_hole); | |
| 380 StoreNoWriteBarrier( | |
| 381 MachineRepresentation::kTagged, adjusted_map_array, | |
| 382 offset, ParameterToTagged(context_index.value(), mode)); | |
| 383 Increment(context_index, 1, mode); | |
| 384 }, | |
| 385 -kPointerSize); | |
| 386 | |
| 387 result.Bind(argument_object); | |
| 388 Goto(&done); | |
| 389 } | |
| 390 | |
| 391 Bind(&no_parameters); | |
| 392 { | |
| 393 Comment("No parameters JSSloppyArgumentsObject"); | |
| 394 GotoIfFixedArraySizeDoesntFitInNewSpace( | |
| 395 argument_count, &runtime, | |
| 396 JSSloppyArgumentsObject::kSize + FixedArray::kHeaderSize, mode); | |
| 397 Node* const native_context = LoadNativeContext(context); | |
| 398 Node* const map = | |
| 399 LoadContextElement(native_context, Context::SLOPPY_ARGUMENTS_MAP_INDEX); | |
| 400 result.Bind(ConstructParametersObjectFromArgs( | |
| 401 map, frame_ptr, argument_count, zero, argument_count, mode, | |
| 402 JSSloppyArgumentsObject::kSize)); | |
| 403 StoreObjectFieldNoWriteBarrier( | |
| 404 result.value(), JSSloppyArgumentsObject::kCalleeOffset, function); | |
| 405 Goto(&done); | |
| 406 } | |
| 407 | |
| 408 Bind(&empty); | |
| 409 { | |
| 410 Comment("Empty JSSloppyArgumentsObject"); | |
| 411 Node* const native_context = LoadNativeContext(context); | |
| 412 Node* const map = | |
| 413 LoadContextElement(native_context, Context::SLOPPY_ARGUMENTS_MAP_INDEX); | |
| 414 Node* arguments; | |
| 415 Node* elements; | |
| 416 Node* unused; | |
| 417 std::tie(arguments, elements, unused) = AllocateArgumentsObject( | |
| 418 map, zero, nullptr, mode, JSSloppyArgumentsObject::kSize); | |
| 419 result.Bind(arguments); | |
| 420 StoreObjectFieldNoWriteBarrier( | |
| 421 result.value(), JSSloppyArgumentsObject::kCalleeOffset, function); | |
| 422 Goto(&done); | |
| 423 } | |
| 424 | |
| 425 Bind(&runtime); | |
| 426 { | |
| 427 result.Bind(CallRuntime(Runtime::kNewSloppyArguments, context, function)); | |
| 428 Goto(&done); | |
| 429 } | |
| 430 | |
| 431 Bind(&done); | |
| 432 return result.value(); | |
| 433 } | |
| 434 | |
| 435 TF_BUILTIN(FastNewSloppyArguments, ArgumentsBuiltinsAssembler) { | |
| 436 Node* function = Parameter(FastNewSloppyArgumentsDescriptor::kFunction); | |
| 437 Node* context = Parameter(FastNewSloppyArgumentsDescriptor::kContext); | |
| 438 Return(EmitFastNewSloppyArguments(context, function)); | |
| 439 } | |
| 440 | |
| 441 } // namespace internal | |
| 442 } // namespace v8 | |
| OLD | NEW |