Skip to content

Commit 5a52380

Browse files
clover2123ksh8281
authored andcommitted
Implement Immutable Prototype Exotic Object
Signed-off-by: HyukWoo Park <[email protected]>
1 parent 99f7a16 commit 5a52380

File tree

11 files changed

+79
-33
lines changed

11 files changed

+79
-33
lines changed

src/builtins/BuiltinObject.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,10 +347,9 @@ static Value builtinObjectSetPrototypeOf(ExecutionState& state, Value thisValue,
347347

348348
// 5. Let status be O.[[SetPrototypeOf]](proto).
349349
Object* obj = object.toObject(state);
350-
bool status = obj->setPrototype(state, proto);
351350

352351
// 7. If status is false, throw a TypeError exception.
353-
if (!status) {
352+
if (!obj->setPrototype(state, proto)) {
354353
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, state.context()->staticStrings().Object.string(), false, state.context()->staticStrings().setPrototypeOf.string(), "can't set prototype of this object");
355354
return Value();
356355
}

src/builtins/BuiltinSet.cpp

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ static Value builtinSetConstructor(ExecutionState& state, Value thisValue, size_
3838
// Let set be ? OrdinaryCreateFromConstructor(NewTarget, "%SetPrototype%", « [[SetData]] »).
3939
// Set set's [[SetData]] internal slot to a new empty List.
4040
Object* proto = Object::getPrototypeFromConstructor(state, newTarget.value(), [](ExecutionState& state, Context* constructorRealm) -> Object* {
41-
return constructorRealm->globalObject()->setPrototype();
41+
return constructorRealm->globalObject()->setPrototypeObject();
4242
});
4343
SetObject* set = new SetObject(state, proto);
4444

@@ -207,43 +207,43 @@ void GlobalObject::installSet(ExecutionState& state)
207207
m_set->directDefineOwnProperty(state, ObjectPropertyName(state.context()->vmInstance()->globalSymbols().species), desc);
208208
}
209209

210-
m_setPrototype = new PrototypeObject(state);
211-
m_setPrototype->setGlobalIntrinsicObject(state, true);
212-
m_setPrototype->directDefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().constructor), ObjectPropertyDescriptor(m_set, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
210+
m_setPrototypeObject = new PrototypeObject(state);
211+
m_setPrototypeObject->setGlobalIntrinsicObject(state, true);
212+
m_setPrototypeObject->directDefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().constructor), ObjectPropertyDescriptor(m_set, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
213213

214-
m_setPrototype->directDefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().clear),
215-
ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().clear, builtinSetClear, 0, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
214+
m_setPrototypeObject->directDefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().clear),
215+
ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().clear, builtinSetClear, 0, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
216216

217-
m_setPrototype->directDefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().stringDelete),
218-
ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().stringDelete, builtinSetDelete, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
217+
m_setPrototypeObject->directDefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().stringDelete),
218+
ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().stringDelete, builtinSetDelete, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
219219

220-
m_setPrototype->directDefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().has),
221-
ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().has, builtinSetHas, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
220+
m_setPrototypeObject->directDefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().has),
221+
ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().has, builtinSetHas, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
222222

223-
m_setPrototype->directDefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().add),
224-
ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().add, builtinSetAdd, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
223+
m_setPrototypeObject->directDefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().add),
224+
ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().add, builtinSetAdd, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
225225

226-
m_setPrototype->directDefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().forEach),
227-
ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().forEach, builtinSetForEach, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
226+
m_setPrototypeObject->directDefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().forEach),
227+
ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().forEach, builtinSetForEach, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
228228

229229
auto valuesFn = new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().values, builtinSetValues, 0, NativeFunctionInfo::Strict));
230230
auto values = ObjectPropertyDescriptor(valuesFn, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent));
231-
m_setPrototype->directDefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().values), values);
232-
m_setPrototype->directDefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().keys), values);
231+
m_setPrototypeObject->directDefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().values), values);
232+
m_setPrototypeObject->directDefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().keys), values);
233233

234-
m_setPrototype->directDefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().entries),
235-
ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().entries, builtinSetEntries, 0, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
234+
m_setPrototypeObject->directDefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().entries),
235+
ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().entries, builtinSetEntries, 0, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
236236

237-
m_setPrototype->directDefineOwnProperty(state, ObjectPropertyName(state.context()->vmInstance()->globalSymbols().iterator),
238-
ObjectPropertyDescriptor(valuesFn, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
237+
m_setPrototypeObject->directDefineOwnProperty(state, ObjectPropertyName(state.context()->vmInstance()->globalSymbols().iterator),
238+
ObjectPropertyDescriptor(valuesFn, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
239239

240-
m_setPrototype->directDefineOwnProperty(state, ObjectPropertyName(state.context()->vmInstance()->globalSymbols().toStringTag),
241-
ObjectPropertyDescriptor(Value(state.context()->staticStrings().Set.string()), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::ConfigurablePresent)));
240+
m_setPrototypeObject->directDefineOwnProperty(state, ObjectPropertyName(state.context()->vmInstance()->globalSymbols().toStringTag),
241+
ObjectPropertyDescriptor(Value(state.context()->staticStrings().Set.string()), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::ConfigurablePresent)));
242242
JSGetterSetter gs(
243243
new NativeFunctionObject(state, NativeFunctionInfo(AtomicString(state, String::fromASCII("get size")), builtinSetSizeGetter, 0, NativeFunctionInfo::Strict)),
244244
Value(Value::EmptyValue));
245245
ObjectPropertyDescriptor desc(gs, ObjectPropertyDescriptor::ConfigurablePresent);
246-
m_setPrototype->directDefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().size), desc);
246+
m_setPrototypeObject->directDefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().size), desc);
247247

248248
m_setIteratorPrototype = new PrototypeObject(state, m_iteratorPrototype);
249249
m_setIteratorPrototype->setGlobalIntrinsicObject(state, true);
@@ -254,7 +254,7 @@ void GlobalObject::installSet(ExecutionState& state)
254254
m_setIteratorPrototype->directDefineOwnProperty(state, ObjectPropertyName(state.context()->vmInstance()->globalSymbols().toStringTag),
255255
ObjectPropertyDescriptor(Value(String::fromASCII("Set Iterator")), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::ConfigurablePresent)));
256256

257-
m_set->setFunctionPrototype(state, m_setPrototype);
257+
m_set->setFunctionPrototype(state, m_setPrototypeObject);
258258
redefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().Set),
259259
ObjectPropertyDescriptor(m_set, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
260260
}

src/runtime/GlobalObject.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
namespace Escargot {
4646

4747
GlobalObject::GlobalObject(ExecutionState& state)
48-
: PrototypeObject(state, Object::createBuiltinObjectPrototype(state))
48+
: ImmutablePrototypeObject(state, Object::createBuiltinObjectPrototype(state))
4949
, m_context(state.context())
5050
#define INIT_BUILTIN_VALUE(builtin, TYPE, objName) \
5151
, m_##builtin(nullptr)

src/runtime/GlobalObject.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ class FunctionObject;
188188
F(regexpSplitMethod, FunctionObject, objName)
189189
#define GLOBALOBJECT_BUILTIN_SET(F, objName) \
190190
F(set, FunctionObject, objName) \
191-
F(setPrototype, Object, objName) \
191+
F(setPrototypeObject, Object, objName) \
192192
F(setIteratorPrototype, Object, objName)
193193
#define GLOBALOBJECT_BUILTIN_STRING(F, objName) \
194194
F(string, FunctionObject, objName) \
@@ -318,7 +318,7 @@ class FunctionObject;
318318

319319
Value builtinSpeciesGetter(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget);
320320

321-
class GlobalObject : public PrototypeObject {
321+
class GlobalObject : public ImmutablePrototypeObject {
322322
public:
323323
friend class GlobalEnvironmentRecord;
324324

src/runtime/GlobalObjectProxyObject.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ Object* GlobalObjectProxyObject::getPrototypeObject(ExecutionState& state)
9797
bool GlobalObjectProxyObject::setPrototype(ExecutionState& state, const Value& proto)
9898
{
9999
checkSecurity(state, GlobalObjectProxyObjectRef::AccessOperationType::Write, Optional<AtomicString>());
100-
return m_target->Object::setPrototype(state, proto);
100+
return m_target->setPrototype(state, proto);
101101
}
102102

103103
Object::OwnPropertyKeyVector GlobalObjectProxyObject::ownPropertyKeys(ExecutionState& state)

src/runtime/Object.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,7 @@ bool Object::isConcatSpreadable(ExecutionState& state)
582582

583583
Object* Object::createBuiltinObjectPrototype(ExecutionState& state)
584584
{
585-
Object* obj = new PrototypeObject(state, PrototypeObject::__ForGlobalBuiltin__);
585+
Object* obj = new ImmutablePrototypeObject(state, ImmutablePrototypeObject::__ForGlobalBuiltin__);
586586
obj->markThisObjectDontNeedStructureTransitionTable();
587587
return obj;
588588
}

src/runtime/PrototypeObject.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,17 @@ void PrototypeObject::markAsPrototypeObject(ExecutionState& state)
4646
}
4747
}
4848

49+
bool ImmutablePrototypeObject::setPrototype(ExecutionState& state, const Value& proto)
50+
{
51+
// Let current be ? O.[[GetPrototypeOf]]().
52+
Value current = getPrototype(state);
53+
// If SameValue(V, current) is true, return true.
54+
if (current == proto) {
55+
return true;
56+
}
57+
58+
// Return false.
59+
return false;
60+
}
61+
4962
} // namespace Escargot

src/runtime/PrototypeObject.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,26 @@ class PrototypeObject : public DerivedObject {
4646
}
4747
};
4848

49+
// Immutable Prototype Exotic Objects
50+
// An immutable prototype exotic object is an exotic object that has a [[Prototype]] internal slot
51+
// that will not change once it is initialized.
52+
class ImmutablePrototypeObject : public PrototypeObject {
53+
public:
54+
explicit ImmutablePrototypeObject(ExecutionState& state, Object* proto, size_t defaultSpace = ESCARGOT_OBJECT_BUILTIN_PROPERTY_NUMBER)
55+
: PrototypeObject(state, proto, defaultSpace)
56+
{
57+
}
58+
59+
enum ForGlobalBuiltin { __ForGlobalBuiltin__ };
60+
explicit ImmutablePrototypeObject(ExecutionState& state, ForGlobalBuiltin)
61+
: PrototypeObject(state, PrototypeObject::__ForGlobalBuiltin__)
62+
{
63+
}
64+
65+
// internal [[prototype]]
66+
virtual bool setPrototype(ExecutionState& state, const Value& proto);
67+
};
68+
4969
} // namespace Escargot
5070

5171
#endif

src/runtime/SetObject.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
namespace Escargot {
2626

2727
SetObject::SetObject(ExecutionState& state)
28-
: SetObject(state, state.context()->globalObject()->setPrototype())
28+
: SetObject(state, state.context()->globalObject()->setPrototypeObject())
2929
{
3030
}
3131

tools/test/v8/v8.mjsunit.status

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,20 @@
779779
# outdated
780780
'invalid-lhs': [SKIP],
781781

782+
# can't set prototype of this object
783+
'getter-in-prototype': [SKIP],
784+
'global-deleted-property-ic': [SKIP],
785+
'es6/unscopables': [SKIP],
786+
'regress/readonly3': [SKIP],
787+
'regress/readonly5': [SKIP],
788+
'regress/regress-186': [SKIP],
789+
'regress/regress-447561': [SKIP],
790+
'regress/regress-489151': [SKIP],
791+
'regress/regress-675': [SKIP],
792+
'regress/regress-88591': [SKIP],
793+
'regress/regress-crbug-454091': [SKIP],
794+
'regress/regress-crbug-513472': [SKIP],
795+
782796
## 15. Out of memory
783797

784798
# 32bit addressing on 64bit causes memory allocation failure

0 commit comments

Comments
 (0)