@@ -3732,6 +3732,74 @@ BUILTIN(ObjectProtoToString) {
3732
3732
return *result;
3733
3733
}
3734
3734
3735
+ // -----------------------------------------------------------------------------
3736
+ // ES6 section 21.1 String Objects
3737
+
3738
+ namespace {
3739
+
3740
+ bool ToUint16 (Handle <Object> value, uint16_t * result) {
3741
+ if (value->IsNumber () || Object::ToNumber (value).ToHandle (&value)) {
3742
+ *result = DoubleToUint32 (value->Number ());
3743
+ return true ;
3744
+ }
3745
+ return false ;
3746
+ }
3747
+
3748
+ } // namespace
3749
+
3750
+ // ES6 21.1.2.1 String.fromCharCode ( ...codeUnits )
3751
+ BUILTIN (StringFromCharCode) {
3752
+ HandleScope scope (isolate);
3753
+ // Check resulting string length.
3754
+ int index = 0 ;
3755
+ Handle <String> result;
3756
+ int const length = args.length () - 1 ;
3757
+ if (length == 0 ) return isolate->heap ()->empty_string ();
3758
+ DCHECK_LT (0 , length);
3759
+ // Load the first character code.
3760
+ uint16_t code;
3761
+ if (!ToUint16 (args.at <Object>(1 ), &code)) return isolate->heap ()->exception ();
3762
+ // Assume that the resulting String contains only one byte characters.
3763
+ if (code <= String::kMaxOneByteCharCodeU ) {
3764
+ // Check for single one-byte character fast case.
3765
+ if (length == 1 ) {
3766
+ return *isolate->factory ()->LookupSingleCharacterStringFromCode (code);
3767
+ }
3768
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION (
3769
+ isolate, result, isolate->factory ()->NewRawOneByteString (length));
3770
+ do {
3771
+ Handle <SeqOneByteString>::cast (result)->Set (index , code);
3772
+ if (++index == length) break ;
3773
+ if (!ToUint16 (args.at <Object>(1 + index ), &code)) {
3774
+ return isolate->heap ()->exception ();
3775
+ }
3776
+ } while (code <= String::kMaxOneByteCharCodeU );
3777
+ }
3778
+ // Check if all characters fit into the one byte range.
3779
+ if (index < length) {
3780
+ // Fallback to two byte string.
3781
+ Handle <String> new_result;
3782
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION (
3783
+ isolate, new_result, isolate->factory ()->NewRawTwoByteString (length));
3784
+ for (int new_index = 0 ; new_index < index ; ++new_index) {
3785
+ uint16_t new_code =
3786
+ Handle <SeqOneByteString>::cast (result)->Get (new_index);
3787
+ Handle <SeqTwoByteString>::cast (new_result)->Set (new_index, new_code);
3788
+ }
3789
+ while (true ) {
3790
+ Handle <SeqTwoByteString>::cast (new_result)->Set (index , code);
3791
+ if (++index == length) break ;
3792
+ if (!ToUint16 (args.at <Object>(1 + index ), &code)) {
3793
+ return isolate->heap ()->exception ();
3794
+ }
3795
+ }
3796
+ result = new_result;
3797
+ }
3798
+ return *result;
3799
+ }
3800
+
3801
+ // -----------------------------------------------------------------------------
3802
+ // ES6 section 21.1 ArrayBuffer Objects
3735
3803
3736
3804
// ES6 section 24.1.2.1 ArrayBuffer ( length ) for the [[Call]] case.
3737
3805
BUILTIN (ArrayBufferConstructor) {
0 commit comments