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
3 // found in the LICENSE file.
4
5 #include "src/builtins/builtins-utils-inl.h"
6 #include "src/builtins/builtins.h"
7 #include "src/heap/heap-inl.h" // For public_symbol_table().
8 #include "src/logging/counters.h"
9 #include "src/objects/objects-inl.h"
10
11 namespace v8 {
12 namespace internal {
13
14 // -----------------------------------------------------------------------------
15 // ES #sec-symbol-objects
16
17 // ES #sec-symbol-constructor
BUILTIN(SymbolConstructor)18 BUILTIN(SymbolConstructor) {
19 HandleScope scope(isolate);
20 if (!args.new_target()->IsUndefined(isolate)) { // [[Construct]]
21 THROW_NEW_ERROR_RETURN_FAILURE(
22 isolate, NewTypeError(MessageTemplate::kNotConstructor,
23 isolate->factory()->Symbol_string()));
24 }
25 // [[Call]]
26 Handle<Symbol> result = isolate->factory()->NewSymbol();
27 Handle<Object> description = args.atOrUndefined(isolate, 1);
28 if (!description->IsUndefined(isolate)) {
29 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, description,
30 Object::ToString(isolate, description));
31 result->set_description(String::cast(*description));
32 }
33 return *result;
34 }
35
36 // ES6 section 19.4.2.1 Symbol.for.
BUILTIN(SymbolFor)37 BUILTIN(SymbolFor) {
38 HandleScope scope(isolate);
39 Handle<Object> key_obj = args.atOrUndefined(isolate, 1);
40 Handle<String> key;
41 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key,
42 Object::ToString(isolate, key_obj));
43 return *isolate->SymbolFor(RootIndex::kPublicSymbolTable, key, false);
44 }
45
46 // ES6 section 19.4.2.5 Symbol.keyFor.
BUILTIN(SymbolKeyFor)47 BUILTIN(SymbolKeyFor) {
48 HandleScope scope(isolate);
49 Handle<Object> obj = args.atOrUndefined(isolate, 1);
50 if (!obj->IsSymbol()) {
51 THROW_NEW_ERROR_RETURN_FAILURE(
52 isolate, NewTypeError(MessageTemplate::kSymbolKeyFor, obj));
53 }
54 Handle<Symbol> symbol = Handle<Symbol>::cast(obj);
55 DisallowGarbageCollection no_gc;
56 Object result;
57 if (symbol->is_in_public_symbol_table()) {
58 result = symbol->description();
59 DCHECK(result.IsString());
60 } else {
61 result = ReadOnlyRoots(isolate).undefined_value();
62 }
63 DCHECK_EQ(isolate->heap()->public_symbol_table().SlowReverseLookup(*symbol),
64 result);
65 return result;
66 }
67
68 } // namespace internal
69 } // namespace v8
70