1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_OBJECTS_OPTION_UTILS_H_
#define V8_OBJECTS_OPTION_UTILS_H_
#include "src/common/globals.h"
#include "src/execution/isolate.h"
#include "src/objects/js-objects.h"
#include "src/objects/string.h"
namespace v8 {
namespace internal {
// ecma402/#sec-getoptionsobject and temporal/#sec-getoptionsobject
V8_WARN_UNUSED_RESULT MaybeHandle<JSReceiver> GetOptionsObject(
Isolate* isolate, Handle<Object> options, const char* method_name);
// ecma402/#sec-coerceoptionstoobject
V8_WARN_UNUSED_RESULT MaybeHandle<JSReceiver> CoerceOptionsToObject(
Isolate* isolate, Handle<Object> options, const char* method_name);
// ECMA402 9.2.10. GetOption( options, property, type, values, fallback)
// ecma402/#sec-getoption and temporal/#sec-getoption
//
// This is specialized for the case when type is string.
//
// Instead of passing undefined for the values argument as the spec
// defines, pass in an empty vector.
//
// Returns true if options object has the property and stores the
// result in value. Returns false if the value is not found. The
// caller is required to use fallback value appropriately in this
// case.
//
// method_name is a string denoting the method the call from; used when
// printing the error message.
V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT Maybe<bool> GetStringOption(
Isolate* isolate, Handle<JSReceiver> options, const char* property,
const std::vector<const char*>& values, const char* method_name,
std::unique_ptr<char[]>* result);
// A helper template to get string from option into a enum.
// The enum in the enum_values is the corresponding value to the strings
// in the str_values. If the option does not contains name,
// default_value will be return.
template <typename T>
V8_WARN_UNUSED_RESULT static Maybe<T> GetStringOption(
Isolate* isolate, Handle<JSReceiver> options, const char* name,
const char* method_name, const std::vector<const char*>& str_values,
const std::vector<T>& enum_values, T default_value) {
DCHECK_EQ(str_values.size(), enum_values.size());
std::unique_ptr<char[]> cstr;
Maybe<bool> found =
GetStringOption(isolate, options, name, str_values, method_name, &cstr);
MAYBE_RETURN(found, Nothing<T>());
if (found.FromJust()) {
DCHECK_NOT_NULL(cstr.get());
for (size_t i = 0; i < str_values.size(); i++) {
if (strcmp(cstr.get(), str_values[i]) == 0) {
return Just(enum_values[i]);
}
}
UNREACHABLE();
}
return Just(default_value);
}
// A helper template to get string from option into a enum.
// The enum in the enum_values is the corresponding value to the strings
// in the str_values. If the option does not contains name,
// default_value will be return.
template <typename T>
V8_WARN_UNUSED_RESULT static Maybe<T> GetStringOrBooleanOption(
Isolate* isolate, Handle<JSReceiver> options, const char* property,
const char* method, const std::vector<const char*>& str_values,
const std::vector<T>& enum_values, T true_value, T false_value,
T fallback_value) {
DCHECK_EQ(str_values.size(), enum_values.size());
Factory* factory = isolate->factory();
Handle<String> property_str = factory->NewStringFromAsciiChecked(property);
// 1. Let value be ? Get(options, property).
Handle<Object> value;
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, value,
Object::GetPropertyOrElement(isolate, options, property_str),
Nothing<T>());
// 2. If value is undefined, then return fallback.
if (IsUndefined(*value, isolate)) {
return Just(fallback_value);
}
// 3. If value is true, then return trueValue.
if (IsTrue(*value, isolate)) {
return Just(true_value);
}
// 4. Let valueBoolean be ToBoolean(value).
bool valueBoolean = Object::BooleanValue(*value, isolate);
// 5. If valueBoolean is false, then return valueBoolean.
if (!valueBoolean) {
return Just(false_value);
}
Handle<String> value_str;
// 6. Let value be ? ToString(value).
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, value_str, Object::ToString(isolate, value), Nothing<T>());
// 7. If value is *"true"* or *"false"*, return _fallback_.
if (String::Equals(isolate, value_str, factory->true_string()) ||
String::Equals(isolate, value_str, factory->false_string())) {
return Just(fallback_value);
}
// 8. If values does not contain an element equal to _value_, throw a
// *RangeError* exception.
// 9. Return value.
value_str = String::Flatten(isolate, value_str);
{
DisallowGarbageCollection no_gc;
const String::FlatContent& flat = value_str->GetFlatContent(no_gc);
int32_t length = value_str->length();
for (size_t i = 0; i < str_values.size(); i++) {
if (static_cast<int32_t>(strlen(str_values.at(i))) == length) {
if (flat.IsOneByte()) {
if (CompareCharsEqual(str_values.at(i),
flat.ToOneByteVector().begin(), length)) {
return Just(enum_values[i]);
}
} else {
if (CompareCharsEqual(str_values.at(i), flat.ToUC16Vector().begin(),
length)) {
return Just(enum_values[i]);
}
}
}
}
} // end of no_gc
THROW_NEW_ERROR_RETURN_VALUE(
isolate,
NewRangeError(MessageTemplate::kValueOutOfRange, value,
factory->NewStringFromAsciiChecked(method), property_str),
Nothing<T>());
}
// ECMA402 9.2.10. GetOption( options, property, type, values, fallback)
// ecma402/#sec-getoption
//
// This is specialized for the case when type is boolean.
//
// Returns true if options object has the property and stores the
// result in value. Returns false if the value is not found. The
// caller is required to use fallback value appropriately in this
// case.
//
// method_name is a string denoting the method it called from; used when
// printing the error message.
V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT Maybe<bool> GetBoolOption(
Isolate* isolate, Handle<JSReceiver> options, const char* property,
const char* method_name, bool* result);
V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT Maybe<int> GetNumberOption(
Isolate* isolate, Handle<JSReceiver> options, Handle<String> property,
int min, int max, int fallback);
// #sec-getoption while type is "number"
V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT Maybe<double> GetNumberOptionAsDouble(
Isolate* isolate, Handle<JSReceiver> options, Handle<String> property,
double default_value);
// ecma402/#sec-defaultnumberoption
V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT Maybe<int> DefaultNumberOption(
Isolate* isolate, Handle<Object> value, int min, int max, int fallback,
Handle<String> property);
} // namespace internal
} // namespace v8
#endif // V8_OBJECTS_OPTION_UTILS_H_
|