11use super :: internal_methods:: InternalMethodPropertyContext ;
2+ use crate :: js_error;
23use crate :: value:: JsVariant ;
34use crate :: {
45 Context , JsResult , JsSymbol , JsValue ,
@@ -887,23 +888,28 @@ impl JsObject {
887888 value : JsValue ,
888889 context : & mut Context ,
889890 ) -> JsResult < ( ) > {
890- // 1. If the host is a web browser, then
891- // a. Perform ? HostEnsureCanAddPrivateElement(O).
891+ if !self . extensible ( ) {
892+ return Err ( js_error ! (
893+ TypeError : "cannot add private field to non-extensible class instance"
894+ )
895+ . into ( ) ) ;
896+ }
897+
898+ // 2. If the host is a web browser, then
899+ // a. Perform ? HostEnsureCanAddPrivateElement(O).
892900 context
893901 . host_hooks ( )
894902 . ensure_can_add_private_element ( self , context) ?;
895903
896- // 2 . Let entry be PrivateElementFind(O, P).
904+ // 3 . Let entry be PrivateElementFind(O, P).
897905 let entry = self . private_element_find ( name, false , false ) ;
898906
899- // 3 . If entry is not empty, throw a TypeError exception.
907+ // 4 . If entry is not empty, throw a TypeError exception.
900908 if entry. is_some ( ) {
901- return Err ( JsNativeError :: typ ( )
902- . with_message ( "Private field already exists on prototype" )
903- . into ( ) ) ;
909+ return Err ( js_error ! ( TypeError : "private field already exists on prototype" ) . into ( ) ) ;
904910 }
905911
906- // 4 . Append PrivateElement { [[Key]]: P, [[Kind]]: field, [[Value]]: value } to O.[[PrivateElements]].
912+ // 5 . Append PrivateElement { [[Key]]: P, [[Kind]]: field, [[Value]]: value } to O.[[PrivateElements]].
907913 self . borrow_mut ( )
908914 . private_elements
909915 . push ( ( name. clone ( ) , PrivateElement :: Field ( value) ) ) ;
@@ -931,12 +937,27 @@ impl JsObject {
931937 method,
932938 PrivateElement :: Method ( _) | PrivateElement :: Accessor { .. }
933939 ) ) ;
940+
934941 let ( getter, setter) = if let PrivateElement :: Accessor { getter, setter } = method {
935942 ( getter. is_some ( ) , setter. is_some ( ) )
936943 } else {
937944 ( false , false )
938945 } ;
939946
947+ if !self . extensible ( ) {
948+ return if getter || setter {
949+ Err ( js_error ! (
950+ TypeError : "cannot add private accessor to non-extensible class instance"
951+ )
952+ . into ( ) )
953+ } else {
954+ Err ( js_error ! (
955+ TypeError : "cannot add private method to non-extensible class instance"
956+ )
957+ . into ( ) )
958+ } ;
959+ }
960+
940961 // 2. If the host is a web browser, then
941962 // a. Perform ? HostEnsureCanAddPrivateElement(O).
942963 context
@@ -948,9 +969,17 @@ impl JsObject {
948969
949970 // 4. If entry is not empty, throw a TypeError exception.
950971 if entry. is_some ( ) {
951- return Err ( JsNativeError :: typ ( )
952- . with_message ( "Private method already exists on prototype" )
953- . into ( ) ) ;
972+ return if getter || setter {
973+ Err ( js_error ! (
974+ TypeError : "private accessor already exists on class instance"
975+ )
976+ . into ( ) )
977+ } else {
978+ Err ( js_error ! (
979+ TypeError : "private method already exists on class instance"
980+ )
981+ . into ( ) )
982+ } ;
954983 }
955984
956985 // 5. Append method to O.[[PrivateElements]].
0 commit comments