Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(452)

Side by Side Diff: src/builtins/builtins-object.cc

Issue 2597323002: Object.prototype.toString must reflect mutated @@toStringTag values for primitives (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-5780.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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 #include "src/builtins/builtins-utils.h" 5 #include "src/builtins/builtins-utils.h"
6 #include "src/builtins/builtins.h" 6 #include "src/builtins/builtins.h"
7 #include "src/code-factory.h" 7 #include "src/code-factory.h"
8 #include "src/code-stub-assembler.h" 8 #include "src/code-stub-assembler.h"
9 #include "src/property-descriptor.h" 9 #include "src/property-descriptor.h"
10 10
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 assembler->factory()->NewStringFromStaticChars("]")); 251 assembler->factory()->NewStringFromStaticChars("]"));
252 252
253 Callable callable = CodeFactory::StringAdd( 253 Callable callable = CodeFactory::StringAdd(
254 assembler->isolate(), STRING_ADD_CHECK_NONE, NOT_TENURED); 254 assembler->isolate(), STRING_ADD_CHECK_NONE, NOT_TENURED);
255 255
256 assembler->Return(assembler->CallStub( 256 assembler->Return(assembler->CallStub(
257 callable, context, assembler->CallStub(callable, context, lhs, string), 257 callable, context, assembler->CallStub(callable, context, lhs, string),
258 rhs)); 258 rhs));
259 } 259 }
260 260
261 void ReturnIfPrimitive(CodeStubAssembler* assembler,
262 compiler::Node* instance_type,
263 CodeStubAssembler::Label* return_string,
264 CodeStubAssembler::Label* return_boolean,
265 CodeStubAssembler::Label* return_number) {
266 assembler->GotoIf(assembler->IsStringInstanceType(instance_type),
267 return_string);
268
269 assembler->GotoIf(assembler->Word32Equal(
270 instance_type, assembler->Int32Constant(ODDBALL_TYPE)),
271 return_boolean);
272
273 assembler->GotoIf(
274 assembler->Word32Equal(instance_type,
275 assembler->Int32Constant(HEAP_NUMBER_TYPE)),
276 return_number);
277 }
278
279 } // namespace 261 } // namespace
280 262
281 // ES6 section 19.1.3.6 Object.prototype.toString 263 // ES6 section 19.1.3.6 Object.prototype.toString
282 void Builtins::Generate_ObjectProtoToString( 264 void Builtins::Generate_ObjectProtoToString(
283 compiler::CodeAssemblerState* state) { 265 compiler::CodeAssemblerState* state) {
284 typedef compiler::Node Node; 266 typedef compiler::Node Node;
285 typedef CodeStubAssembler::Label Label; 267 typedef CodeStubAssembler::Label Label;
286 typedef CodeStubAssembler::Variable Variable; 268 typedef CodeStubAssembler::Variable Variable;
287 CodeStubAssembler assembler(state); 269 CodeStubAssembler assembler(state);
288 270
289 Label return_undefined(&assembler, Label::kDeferred), 271 Label return_undefined(&assembler, Label::kDeferred),
290 return_null(&assembler, Label::kDeferred), 272 return_null(&assembler, Label::kDeferred),
291 return_arguments(&assembler, Label::kDeferred), return_array(&assembler), 273 return_arguments(&assembler, Label::kDeferred), return_array(&assembler),
292 return_api(&assembler, Label::kDeferred), return_object(&assembler), 274 return_api(&assembler, Label::kDeferred), return_object(&assembler),
293 return_regexp(&assembler), return_function(&assembler), 275 return_regexp(&assembler), return_function(&assembler),
294 return_error(&assembler), return_date(&assembler), 276 return_error(&assembler), return_date(&assembler),
295 return_string(&assembler), return_boolean(&assembler), 277 return_jsvalue(&assembler), return_jsproxy(&assembler, Label::kDeferred);
296 return_jsvalue(&assembler), return_jsproxy(&assembler, Label::kDeferred),
297 return_number(&assembler);
298 278
299 Label if_isproxy(&assembler, Label::kDeferred); 279 Label if_isproxy(&assembler, Label::kDeferred);
300 280
301 Label checkstringtag(&assembler); 281 Label checkstringtag(&assembler);
302 Label if_tostringtag(&assembler), if_notostringtag(&assembler); 282 Label if_tostringtag(&assembler), if_notostringtag(&assembler);
303 283
304 Node* receiver = assembler.Parameter(0); 284 Node* receiver = assembler.Parameter(0);
305 Node* context = assembler.Parameter(3); 285 Node* context = assembler.Parameter(3);
306 286
307 assembler.GotoIf(assembler.WordEqual(receiver, assembler.UndefinedConstant()), 287 assembler.GotoIf(assembler.WordEqual(receiver, assembler.UndefinedConstant()),
308 &return_undefined); 288 &return_undefined);
309 289
310 assembler.GotoIf(assembler.WordEqual(receiver, assembler.NullConstant()), 290 assembler.GotoIf(assembler.WordEqual(receiver, assembler.NullConstant()),
311 &return_null); 291 &return_null);
312 292
313 assembler.GotoIf(assembler.TaggedIsSmi(receiver), &return_number); 293 Callable to_object = CodeFactory::ToObject(assembler.isolate());
294 receiver = assembler.CallStub(to_object, context, receiver);
314 295
315 Node* receiver_instance_type = assembler.LoadInstanceType(receiver); 296 Node* receiver_instance_type = assembler.LoadInstanceType(receiver);
316 ReturnIfPrimitive(&assembler, receiver_instance_type, &return_string,
317 &return_boolean, &return_number);
318 297
319 // for proxies, check IsArray before getting @@toStringTag 298 // for proxies, check IsArray before getting @@toStringTag
320 Variable var_proxy_is_array(&assembler, MachineRepresentation::kTagged); 299 Variable var_proxy_is_array(&assembler, MachineRepresentation::kTagged);
321 var_proxy_is_array.Bind(assembler.BooleanConstant(false)); 300 var_proxy_is_array.Bind(assembler.BooleanConstant(false));
322 301
323 assembler.Branch( 302 assembler.Branch(
324 assembler.Word32Equal(receiver_instance_type, 303 assembler.Word32Equal(receiver_instance_type,
325 assembler.Int32Constant(JS_PROXY_TYPE)), 304 assembler.Int32Constant(JS_PROXY_TYPE)),
326 &if_isproxy, &checkstringtag); 305 &if_isproxy, &checkstringtag);
327 306
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 case_labels, arraysize(case_values)); 361 case_labels, arraysize(case_values));
383 362
384 assembler.Bind(&return_undefined); 363 assembler.Bind(&return_undefined);
385 assembler.Return(assembler.HeapConstant( 364 assembler.Return(assembler.HeapConstant(
386 assembler.isolate()->factory()->undefined_to_string())); 365 assembler.isolate()->factory()->undefined_to_string()));
387 366
388 assembler.Bind(&return_null); 367 assembler.Bind(&return_null);
389 assembler.Return(assembler.HeapConstant( 368 assembler.Return(assembler.HeapConstant(
390 assembler.isolate()->factory()->null_to_string())); 369 assembler.isolate()->factory()->null_to_string()));
391 370
392 assembler.Bind(&return_number);
393 assembler.Return(assembler.HeapConstant(
394 assembler.isolate()->factory()->number_to_string()));
395
396 assembler.Bind(&return_string);
397 assembler.Return(assembler.HeapConstant(
398 assembler.isolate()->factory()->string_to_string()));
399
400 assembler.Bind(&return_boolean);
401 assembler.Return(assembler.HeapConstant(
402 assembler.isolate()->factory()->boolean_to_string()));
403
404 assembler.Bind(&return_arguments); 371 assembler.Bind(&return_arguments);
405 assembler.Return(assembler.HeapConstant( 372 assembler.Return(assembler.HeapConstant(
406 assembler.isolate()->factory()->arguments_to_string())); 373 assembler.isolate()->factory()->arguments_to_string()));
407 374
408 assembler.Bind(&return_array); 375 assembler.Bind(&return_array);
409 assembler.Return(assembler.HeapConstant( 376 assembler.Return(assembler.HeapConstant(
410 assembler.isolate()->factory()->array_to_string())); 377 assembler.isolate()->factory()->array_to_string()));
411 378
412 assembler.Bind(&return_function); 379 assembler.Bind(&return_function);
413 assembler.Return(assembler.HeapConstant( 380 assembler.Return(assembler.HeapConstant(
(...skipping 13 matching lines...) Expand all
427 394
428 assembler.Bind(&return_api); 395 assembler.Bind(&return_api);
429 { 396 {
430 Node* class_name = 397 Node* class_name =
431 assembler.CallRuntime(Runtime::kClassOf, context, receiver); 398 assembler.CallRuntime(Runtime::kClassOf, context, receiver);
432 ReturnToStringFormat(&assembler, context, class_name); 399 ReturnToStringFormat(&assembler, context, class_name);
433 } 400 }
434 401
435 assembler.Bind(&return_jsvalue); 402 assembler.Bind(&return_jsvalue);
436 { 403 {
404 Label return_boolean(&assembler), return_number(&assembler),
405 return_string(&assembler);
406
437 Node* value = assembler.LoadJSValueValue(receiver); 407 Node* value = assembler.LoadJSValueValue(receiver);
438 assembler.GotoIf(assembler.TaggedIsSmi(value), &return_number); 408 assembler.GotoIf(assembler.TaggedIsSmi(value), &return_number);
409 Node* instance_type = assembler.LoadInstanceType(value);
439 410
440 ReturnIfPrimitive(&assembler, assembler.LoadInstanceType(value), 411 assembler.GotoIf(assembler.IsStringInstanceType(instance_type),
441 &return_string, &return_boolean, &return_number); 412 &return_string);
413 assembler.GotoIf(
414 assembler.Word32Equal(instance_type,
415 assembler.Int32Constant(HEAP_NUMBER_TYPE)),
416 &return_number);
417 assembler.GotoIf(
418 assembler.Word32Equal(instance_type,
419 assembler.Int32Constant(ODDBALL_TYPE)),
420 &return_boolean);
421
422 CSA_ASSERT(&assembler,
423 assembler.Word32Equal(instance_type,
424 assembler.Int32Constant(SYMBOL_TYPE)));
442 assembler.Goto(&return_object); 425 assembler.Goto(&return_object);
426
427 assembler.Bind(&return_string);
428 assembler.Return(assembler.HeapConstant(
429 assembler.isolate()->factory()->string_to_string()));
430
431 assembler.Bind(&return_number);
432 assembler.Return(assembler.HeapConstant(
433 assembler.isolate()->factory()->number_to_string()));
434
435 assembler.Bind(&return_boolean);
436 assembler.Return(assembler.HeapConstant(
437 assembler.isolate()->factory()->boolean_to_string()));
443 } 438 }
444 439
445 assembler.Bind(&return_jsproxy); 440 assembler.Bind(&return_jsproxy);
446 { 441 {
447 assembler.GotoIf(assembler.WordEqual(var_proxy_is_array.value(), 442 assembler.GotoIf(assembler.WordEqual(var_proxy_is_array.value(),
448 assembler.BooleanConstant(true)), 443 assembler.BooleanConstant(true)),
449 &return_array); 444 &return_array);
450 445
451 Node* map = assembler.LoadMap(receiver); 446 Node* map = assembler.LoadMap(receiver);
452 447
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after
1105 CodeStubAssembler assembler(state); 1100 CodeStubAssembler assembler(state);
1106 1101
1107 Node* object = assembler.Parameter(Descriptor::kObject); 1102 Node* object = assembler.Parameter(Descriptor::kObject);
1108 Node* context = assembler.Parameter(Descriptor::kContext); 1103 Node* context = assembler.Parameter(Descriptor::kContext);
1109 1104
1110 assembler.Return(assembler.GetSuperConstructor(object, context)); 1105 assembler.Return(assembler.GetSuperConstructor(object, context));
1111 } 1106 }
1112 1107
1113 } // namespace internal 1108 } // namespace internal
1114 } // namespace v8 1109 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-5780.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698