@@ -3732,6 +3732,74 @@ BUILTIN(ObjectProtoToString) {
37323732 return *result;
37333733}
37343734
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
37353803
37363804// ES6 section 24.1.2.1 ArrayBuffer ( length ) for the [[Call]] case.
37373805BUILTIN (ArrayBufferConstructor) {
0 commit comments