@ -2,11 +2,22 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
var $arrayConcat ;
var $arrayJoin ;
var $arrayPush ;
var $arrayPop ;
var $arrayShift ;
var $arraySlice ;
var $arraySplice ;
var $arrayUnshift ;
( function ( global , shared , exports ) {
"use strict" ;
"use strict" ;
// This file relies on the fact that the following declarations have been made
% CheckIsBootstrapping ( ) ;
// in runtime.js:
// var $Array = global.Array;
var GlobalArray = global . Array ;
// -------------------------------------------------------------------
// -------------------------------------------------------------------
@ -185,7 +196,7 @@ function ConvertToString(x) {
// Assumes x is a non-string.
// Assumes x is a non-string.
if ( IS_NUMBER ( x ) ) return % _ NumberToString ( x ) ;
if ( IS_NUMBER ( x ) ) return % _ NumberToString ( x ) ;
if ( IS_BOOLEAN ( x ) ) return x ? 'true' : 'false' ;
if ( IS_BOOLEAN ( x ) ) return x ? 'true' : 'false' ;
return ( IS_NULL_OR_UNDEFINED ( x ) ) ? '' : % ToString ( % D efaultString( x ) ) ;
return ( IS_NULL_OR_UNDEFINED ( x ) ) ? '' : $toString ( $d efaultString( x ) ) ;
}
}
@ -196,8 +207,8 @@ function ConvertToLocaleString(e) {
// According to ES5, section 15.4.4.3, the toLocaleString conversion
// According to ES5, section 15.4.4.3, the toLocaleString conversion
// must throw a TypeError if ToObject(e).toLocaleString isn't
// must throw a TypeError if ToObject(e).toLocaleString isn't
// callable.
// callable.
var e_obj = T oObject( e ) ;
var e_obj = $t oObject( e ) ;
return % T oString( e_obj . toLocaleString ( ) ) ;
return $t oString( e_obj . toLocaleString ( ) ) ;
}
}
}
}
@ -357,18 +368,18 @@ function ArrayToString() {
}
}
array = this ;
array = this ;
} else {
} else {
array = T oObject( this ) ;
array = $t oObject( this ) ;
func = array . join ;
func = array . join ;
}
}
if ( ! IS_SPEC_FUNCTION ( func ) ) {
if ( ! IS_SPEC_FUNCTION ( func ) ) {
return % _ CallFunction ( array , DefaultO bjectToString) ;
return % _ CallFunction ( array , $o bjectToString) ;
}
}
return % _ CallFunction ( array , func ) ;
return % _ CallFunction ( array , func ) ;
}
}
function ArrayToLocaleString ( ) {
function ArrayToLocaleString ( ) {
var array = T oObject( this ) ;
var array = $t oObject( this ) ;
var arrayLen = array . length ;
var arrayLen = array . length ;
var len = TO_UINT32 ( arrayLen ) ;
var len = TO_UINT32 ( arrayLen ) ;
if ( len === 0 ) return "" ;
if ( len === 0 ) return "" ;
@ -384,7 +395,7 @@ function ArrayJoin(separator) {
if ( IS_UNDEFINED ( separator ) ) {
if ( IS_UNDEFINED ( separator ) ) {
separator = ',' ;
separator = ',' ;
} else if ( ! IS_STRING ( separator ) ) {
} else if ( ! IS_STRING ( separator ) ) {
separator = N onStringToString( separator ) ;
separator = $n onStringToString( separator ) ;
}
}
var result = % _ FastOneByteArrayJoin ( array , separator ) ;
var result = % _ FastOneByteArrayJoin ( array , separator ) ;
@ -395,7 +406,7 @@ function ArrayJoin(separator) {
var e = array [ 0 ] ;
var e = array [ 0 ] ;
if ( IS_STRING ( e ) ) return e ;
if ( IS_STRING ( e ) ) return e ;
if ( IS_NULL_OR_UNDEFINED ( e ) ) return '' ;
if ( IS_NULL_OR_UNDEFINED ( e ) ) return '' ;
return N onStringToString( e ) ;
return $n onStringToString( e ) ;
}
}
return Join ( array , length , separator , ConvertToString ) ;
return Join ( array , length , separator , ConvertToString ) ;
@ -407,17 +418,18 @@ function ObservedArrayPop(n) {
var value = this [ n ] ;
var value = this [ n ] ;
try {
try {
BeginPerformSplice ( this ) ;
$observe BeginPerformSplice( this ) ;
delete this [ n ] ;
delete this [ n ] ;
this . length = n ;
this . length = n ;
} finally {
} finally {
EndPerformSplice ( this ) ;
$observe EndPerformSplice( this ) ;
EnqueueSpliceRecord ( this , n , [ value ] , 0 ) ;
$observe EnqueueSpliceRecord( this , n , [ value ] , 0 ) ;
}
}
return value ;
return value ;
}
}
// Removes the last element from the array and returns it. See
// Removes the last element from the array and returns it. See
// ECMA-262, section 15.4.4.6.
// ECMA-262, section 15.4.4.6.
function ArrayPop ( ) {
function ArrayPop ( ) {
@ -435,7 +447,7 @@ function ArrayPop() {
n -- ;
n -- ;
var value = array [ n ] ;
var value = array [ n ] ;
D elete( array , T oName( n ) , true ) ;
$d elete( array , $t oName( n ) , true ) ;
array . length = n ;
array . length = n ;
return value ;
return value ;
}
}
@ -446,20 +458,21 @@ function ObservedArrayPush() {
var m = % _ ArgumentsLength ( ) ;
var m = % _ ArgumentsLength ( ) ;
try {
try {
BeginPerformSplice ( this ) ;
$observe BeginPerformSplice( this ) ;
for ( var i = 0 ; i < m ; i ++ ) {
for ( var i = 0 ; i < m ; i ++ ) {
this [ i + n ] = % _ Arguments ( i ) ;
this [ i + n ] = % _ Arguments ( i ) ;
}
}
var new_length = n + m ;
var new_length = n + m ;
this . length = new_length ;
this . length = new_length ;
} finally {
} finally {
EndPerformSplice ( this ) ;
$observe EndPerformSplice( this ) ;
EnqueueSpliceRecord ( this , n , [ ] , m ) ;
$observe EnqueueSpliceRecord( this , n , [ ] , m ) ;
}
}
return new_length ;
return new_length ;
}
}
// Appends the arguments to the end of the array and returns the new
// Appends the arguments to the end of the array and returns the new
// length of the array. See ECMA-262, section 15.4.4.7.
// length of the array. See ECMA-262, section 15.4.4.7.
function ArrayPush ( ) {
function ArrayPush ( ) {
@ -488,7 +501,7 @@ function ArrayPush() {
function ArrayConcatJS ( arg1 ) { // length == 1
function ArrayConcatJS ( arg1 ) { // length == 1
CHECK_OBJECT_COERCIBLE ( this , "Array.prototype.concat" ) ;
CHECK_OBJECT_COERCIBLE ( this , "Array.prototype.concat" ) ;
var array = T oObject( this ) ;
var array = $t oObject( this ) ;
var arg_count = % _ ArgumentsLength ( ) ;
var arg_count = % _ ArgumentsLength ( ) ;
var arrays = new InternalArray ( 1 + arg_count ) ;
var arrays = new InternalArray ( 1 + arg_count ) ;
arrays [ 0 ] = array ;
arrays [ 0 ] = array ;
@ -584,17 +597,18 @@ function ObservedArrayShift(len) {
var first = this [ 0 ] ;
var first = this [ 0 ] ;
try {
try {
BeginPerformSplice ( this ) ;
$observe BeginPerformSplice( this ) ;
SimpleMove ( this , 0 , 1 , len , 0 ) ;
SimpleMove ( this , 0 , 1 , len , 0 ) ;
this . length = len - 1 ;
this . length = len - 1 ;
} finally {
} finally {
EndPerformSplice ( this ) ;
$observe EndPerformSplice( this ) ;
EnqueueSpliceRecord ( this , 0 , [ first ] , 0 ) ;
$observe EnqueueSpliceRecord( this , 0 , [ first ] , 0 ) ;
}
}
return first ;
return first ;
}
}
function ArrayShift ( ) {
function ArrayShift ( ) {
CHECK_OBJECT_COERCIBLE ( this , "Array.prototype.shift" ) ;
CHECK_OBJECT_COERCIBLE ( this , "Array.prototype.shift" ) ;
@ -606,10 +620,7 @@ function ArrayShift() {
return ;
return ;
}
}
if ( ObjectIsSealed ( array ) ) {
if ( $objectIsSealed ( array ) ) throw MakeTypeError ( kArrayFunctionsOnSealed ) ;
throw MakeTypeError ( "array_functions_change_sealed" ,
[ "Array.prototype.shift" ] ) ;
}
if ( % IsObserved ( array ) )
if ( % IsObserved ( array ) )
return ObservedArrayShift . call ( array , len ) ;
return ObservedArrayShift . call ( array , len ) ;
@ -627,12 +638,13 @@ function ArrayShift() {
return first ;
return first ;
}
}
function ObservedArrayUnshift ( ) {
function ObservedArrayUnshift ( ) {
var len = TO_UINT32 ( this . length ) ;
var len = TO_UINT32 ( this . length ) ;
var num_arguments = % _ ArgumentsLength ( ) ;
var num_arguments = % _ ArgumentsLength ( ) ;
try {
try {
BeginPerformSplice ( this ) ;
$observe BeginPerformSplice( this ) ;
SimpleMove ( this , 0 , 0 , len , num_arguments ) ;
SimpleMove ( this , 0 , 0 , len , num_arguments ) ;
for ( var i = 0 ; i < num_arguments ; i ++ ) {
for ( var i = 0 ; i < num_arguments ; i ++ ) {
this [ i ] = % _ Arguments ( i ) ;
this [ i ] = % _ Arguments ( i ) ;
@ -640,13 +652,14 @@ function ObservedArrayUnshift() {
var new_length = len + num_arguments ;
var new_length = len + num_arguments ;
this . length = new_length ;
this . length = new_length ;
} finally {
} finally {
EndPerformSplice ( this ) ;
$observe EndPerformSplice( this ) ;
EnqueueSpliceRecord ( this , 0 , [ ] , num_arguments ) ;
$observe EnqueueSpliceRecord( this , 0 , [ ] , num_arguments ) ;
}
}
return new_length ;
return new_length ;
}
}
function ArrayUnshift ( arg1 ) { // length == 1
function ArrayUnshift ( arg1 ) { // length == 1
CHECK_OBJECT_COERCIBLE ( this , "Array.prototype.unshift" ) ;
CHECK_OBJECT_COERCIBLE ( this , "Array.prototype.unshift" ) ;
@ -658,7 +671,7 @@ function ArrayUnshift(arg1) { // length == 1
var num_arguments = % _ ArgumentsLength ( ) ;
var num_arguments = % _ ArgumentsLength ( ) ;
if ( len > 0 && UseSparseVariant ( array , len , IS_ARRAY ( array ) , len ) &&
if ( len > 0 && UseSparseVariant ( array , len , IS_ARRAY ( array ) , len ) &&
! O bjectIsSealed( array ) ) {
! $o bjectIsSealed ( array ) ) {
SparseMove ( array , 0 , 0 , len , num_arguments ) ;
SparseMove ( array , 0 , 0 , len , num_arguments ) ;
} else {
} else {
SimpleMove ( array , 0 , 0 , len , num_arguments ) ;
SimpleMove ( array , 0 , 0 , len , num_arguments ) ;
@ -758,7 +771,7 @@ function ObservedArraySplice(start, delete_count) {
var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0 ;
var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0 ;
try {
try {
BeginPerformSplice ( this ) ;
$observe BeginPerformSplice( this ) ;
SimpleSlice ( this , start_i , del_count , len , deleted_elements ) ;
SimpleSlice ( this , start_i , del_count , len , deleted_elements ) ;
SimpleMove ( this , start_i , del_count , len , num_elements_to_add ) ;
SimpleMove ( this , start_i , del_count , len , num_elements_to_add ) ;
@ -774,12 +787,12 @@ function ObservedArraySplice(start, delete_count) {
this . length = len - del_count + num_elements_to_add ;
this . length = len - del_count + num_elements_to_add ;
} finally {
} finally {
EndPerformSplice ( this ) ;
$observe EndPerformSplice( this ) ;
if ( deleted_elements . length || num_elements_to_add ) {
if ( deleted_elements . length || num_elements_to_add ) {
EnqueueSpliceRecord ( this ,
$observe EnqueueSpliceRecord( this ,
start_i ,
start_i ,
deleted_elements . slice ( ) ,
deleted_elements . slice ( ) ,
num_elements_to_add ) ;
num_elements_to_add ) ;
}
}
}
}
@ -804,12 +817,10 @@ function ArraySplice(start, delete_count) {
deleted_elements . length = del_count ;
deleted_elements . length = del_count ;
var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0 ;
var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0 ;
if ( del_count != num_elements_to_add && ObjectIsSealed ( array ) ) {
if ( del_count != num_elements_to_add && $objectIsSealed ( array ) ) {
throw MakeTypeError ( "array_functions_change_sealed" ,
throw MakeTypeError ( kArrayFunctionsOnSealed ) ;
[ "Array.prototype.splice" ] ) ;
} else if ( del_count > 0 && $objectIsFrozen ( array ) ) {
} else if ( del_count > 0 && ObjectIsFrozen ( array ) ) {
throw MakeTypeError ( kArrayFunctionsOnFrozen ) ;
throw MakeTypeError ( "array_functions_on_frozen" ,
[ "Array.prototype.splice" ] ) ;
}
}
var changed_elements = del_count ;
var changed_elements = del_count ;
@ -855,20 +866,18 @@ function ArraySort(comparefn) {
if ( % _ IsSmi ( x ) && % _ IsSmi ( y ) ) {
if ( % _ IsSmi ( x ) && % _ IsSmi ( y ) ) {
return % SmiLexicographicCompare ( x , y ) ;
return % SmiLexicographicCompare ( x , y ) ;
}
}
x = T oString( x ) ;
x = $t oString( x ) ;
y = T oString( y ) ;
y = $t oString( y ) ;
if ( x == y ) return 0 ;
if ( x == y ) return 0 ;
else return x < y ? - 1 : 1 ;
else return x < y ? - 1 : 1 ;
} ;
} ;
}
}
var receiver = % GetDefaultReceiver ( comparefn ) ;
var InsertionSort = function InsertionSort ( a , from , to ) {
var InsertionSort = function InsertionSort ( a , from , to ) {
for ( var i = from + 1 ; i < to ; i ++ ) {
for ( var i = from + 1 ; i < to ; i ++ ) {
var element = a [ i ] ;
var element = a [ i ] ;
for ( var j = i - 1 ; j >= from ; j -- ) {
for ( var j = i - 1 ; j >= from ; j -- ) {
var tmp = a [ j ] ;
var tmp = a [ j ] ;
var order = % _ CallFunction ( receiver , tmp , element , comparefn ) ;
var order = % _ CallFunction ( UNDEFINED , tmp , element , comparefn ) ;
if ( order > 0 ) {
if ( order > 0 ) {
a [ j + 1 ] = tmp ;
a [ j + 1 ] = tmp ;
} else {
} else {
@ -887,7 +896,7 @@ function ArraySort(comparefn) {
t_array [ j ] = [ i , a [ i ] ] ;
t_array [ j ] = [ i , a [ i ] ] ;
}
}
% _ CallFunction ( t_array , function ( a , b ) {
% _ CallFunction ( t_array , function ( a , b ) {
return % _ CallFunction ( receiver , a [ 1 ] , b [ 1 ] , comparefn ) ;
return % _ CallFunction ( UNDEFINED , a [ 1 ] , b [ 1 ] , comparefn ) ;
} , ArraySort ) ;
} , ArraySort ) ;
var third_index = t_array [ t_array . length >> 1 ] [ 0 ] ;
var third_index = t_array [ t_array . length >> 1 ] [ 0 ] ;
return third_index ;
return third_index ;
@ -910,14 +919,14 @@ function ArraySort(comparefn) {
var v0 = a [ from ] ;
var v0 = a [ from ] ;
var v1 = a [ to - 1 ] ;
var v1 = a [ to - 1 ] ;
var v2 = a [ third_index ] ;
var v2 = a [ third_index ] ;
var c01 = % _ CallFunction ( receiver , v0 , v1 , comparefn ) ;
var c01 = % _ CallFunction ( UNDEFINED , v0 , v1 , comparefn ) ;
if ( c01 > 0 ) {
if ( c01 > 0 ) {
// v1 < v0, so swap them.
// v1 < v0, so swap them.
var tmp = v0 ;
var tmp = v0 ;
v0 = v1 ;
v0 = v1 ;
v1 = tmp ;
v1 = tmp ;
} // v0 <= v1.
} // v0 <= v1.
var c02 = % _ CallFunction ( receiver , v0 , v2 , comparefn ) ;
var c02 = % _ CallFunction ( UNDEFINED , v0 , v2 , comparefn ) ;
if ( c02 >= 0 ) {
if ( c02 >= 0 ) {
// v2 <= v0 <= v1.
// v2 <= v0 <= v1.
var tmp = v0 ;
var tmp = v0 ;
@ -926,7 +935,7 @@ function ArraySort(comparefn) {
v1 = tmp ;
v1 = tmp ;
} else {
} else {
// v0 <= v1 && v0 < v2
// v0 <= v1 && v0 < v2
var c12 = % _ CallFunction ( receiver , v1 , v2 , comparefn ) ;
var c12 = % _ CallFunction ( UNDEFINED , v1 , v2 , comparefn ) ;
if ( c12 > 0 ) {
if ( c12 > 0 ) {
// v0 <= v2 < v1
// v0 <= v2 < v1
var tmp = v1 ;
var tmp = v1 ;
@ -947,7 +956,7 @@ function ArraySort(comparefn) {
// From i to high_start are elements that haven't been compared yet.
// From i to high_start are elements that haven't been compared yet.
partition : for ( var i = low_end + 1 ; i < high_start ; i ++ ) {
partition : for ( var i = low_end + 1 ; i < high_start ; i ++ ) {
var element = a [ i ] ;
var element = a [ i ] ;
var order = % _ CallFunction ( receiver , element , pivot , comparefn ) ;
var order = % _ CallFunction ( UNDEFINED , element , pivot , comparefn ) ;
if ( order < 0 ) {
if ( order < 0 ) {
a [ i ] = a [ low_end ] ;
a [ i ] = a [ low_end ] ;
a [ low_end ] = element ;
a [ low_end ] = element ;
@ -957,7 +966,7 @@ function ArraySort(comparefn) {
high_start -- ;
high_start -- ;
if ( high_start == i ) break partition ;
if ( high_start == i ) break partition ;
var top_elem = a [ high_start ] ;
var top_elem = a [ high_start ] ;
order = % _ CallFunction ( receiver , top_elem , pivot , comparefn ) ;
order = % _ CallFunction ( UNDEFINED , top_elem , pivot , comparefn ) ;
} while ( order > 0 ) ;
} while ( order > 0 ) ;
a [ i ] = a [ high_start ] ;
a [ i ] = a [ high_start ] ;
a [ high_start ] = element ;
a [ high_start ] = element ;
@ -1139,20 +1148,18 @@ function ArrayFilter(f, receiver) {
// Pull out the length so that modifications to the length in the
// Pull out the length so that modifications to the length in the
// loop will not affect the looping and side effects are visible.
// loop will not affect the looping and side effects are visible.
var array = T oObject( this ) ;
var array = $t oObject( this ) ;
var length = T oUint32( array . length ) ;
var length = $t oUint32( array . length ) ;
if ( ! IS_SPEC_FUNCTION ( f ) ) {
if ( ! IS_SPEC_FUNCTION ( f ) ) throw MakeTypeError ( kCalledNonCallable , f ) ;
throw MakeTypeError ( 'called_non_callable' , [ f ] ) ;
}
var needs_wrapper = false ;
var needs_wrapper = false ;
if ( IS_NULL_OR_UNDEFINED ( receiver ) ) {
if ( IS_NULL ( receiver ) ) {
receiver = % GetDefaultReceiver ( f ) || receiver ;
if ( % IsSloppyModeFunction ( f ) ) receiver = UNDEFINED ;
} else {
} else if ( ! IS_UNDEFINED ( receiver ) ) {
needs_wrapper = SHOULD_CREATE_WRAPPER ( f , receiver ) ;
needs_wrapper = SHOULD_CREATE_WRAPPER ( f , receiver ) ;
}
}
var result = new $ Array( ) ;
var result = new Global Array( ) ;
var accumulator = new InternalArray ( ) ;
var accumulator = new InternalArray ( ) ;
var accumulator_length = 0 ;
var accumulator_length = 0 ;
var is_array = IS_ARRAY ( array ) ;
var is_array = IS_ARRAY ( array ) ;
@ -1162,7 +1169,7 @@ function ArrayFilter(f, receiver) {
var element = array [ i ] ;
var element = array [ i ] ;
// Prepare break slots for debugger step in.
// Prepare break slots for debugger step in.
if ( stepping ) % DebugPrepareStepInIfStepping ( f ) ;
if ( stepping ) % DebugPrepareStepInIfStepping ( f ) ;
var new_receiver = needs_wrapper ? T oObject( receiver ) : receiver ;
var new_receiver = needs_wrapper ? $t oObject( receiver ) : receiver ;
if ( % _ CallFunction ( new_receiver , element , i , array , f ) ) {
if ( % _ CallFunction ( new_receiver , element , i , array , f ) ) {
accumulator [ accumulator_length ++ ] = element ;
accumulator [ accumulator_length ++ ] = element ;
}
}
@ -1178,16 +1185,14 @@ function ArrayForEach(f, receiver) {
// Pull out the length so that modifications to the length in the
// Pull out the length so that modifications to the length in the
// loop will not affect the looping and side effects are visible.
// loop will not affect the looping and side effects are visible.
var array = T oObject( this ) ;
var array = $t oObject( this ) ;
var length = TO_UINT32 ( array . length ) ;
var length = TO_UINT32 ( array . length ) ;
if ( ! IS_SPEC_FUNCTION ( f ) ) {
if ( ! IS_SPEC_FUNCTION ( f ) ) throw MakeTypeError ( kCalledNonCallable , f ) ;
throw MakeTypeError ( 'called_non_callable' , [ f ] ) ;
}
var needs_wrapper = false ;
var needs_wrapper = false ;
if ( IS_NULL_OR_UNDEFINED ( receiver ) ) {
if ( IS_NULL ( receiver ) ) {
receiver = % GetDefaultReceiver ( f ) || receiver ;
if ( % IsSloppyModeFunction ( f ) ) receiver = UNDEFINED ;
} else {
} else if ( ! IS_UNDEFINED ( receiver ) ) {
needs_wrapper = SHOULD_CREATE_WRAPPER ( f , receiver ) ;
needs_wrapper = SHOULD_CREATE_WRAPPER ( f , receiver ) ;
}
}
@ -1198,7 +1203,7 @@ function ArrayForEach(f, receiver) {
var element = array [ i ] ;
var element = array [ i ] ;
// Prepare break slots for debugger step in.
// Prepare break slots for debugger step in.
if ( stepping ) % DebugPrepareStepInIfStepping ( f ) ;
if ( stepping ) % DebugPrepareStepInIfStepping ( f ) ;
var new_receiver = needs_wrapper ? T oObject( receiver ) : receiver ;
var new_receiver = needs_wrapper ? $t oObject( receiver ) : receiver ;
% _ CallFunction ( new_receiver , element , i , array , f ) ;
% _ CallFunction ( new_receiver , element , i , array , f ) ;
}
}
}
}
@ -1212,16 +1217,14 @@ function ArraySome(f, receiver) {
// Pull out the length so that modifications to the length in the
// Pull out the length so that modifications to the length in the
// loop will not affect the looping and side effects are visible.
// loop will not affect the looping and side effects are visible.
var array = T oObject( this ) ;
var array = $t oObject( this ) ;
var length = TO_UINT32 ( array . length ) ;
var length = TO_UINT32 ( array . length ) ;
if ( ! IS_SPEC_FUNCTION ( f ) ) {
if ( ! IS_SPEC_FUNCTION ( f ) ) throw MakeTypeError ( kCalledNonCallable , f ) ;
throw MakeTypeError ( 'called_non_callable' , [ f ] ) ;
}
var needs_wrapper = false ;
var needs_wrapper = false ;
if ( IS_NULL_OR_UNDEFINED ( receiver ) ) {
if ( IS_NULL ( receiver ) ) {
receiver = % GetDefaultReceiver ( f ) || receiver ;
if ( % IsSloppyModeFunction ( f ) ) receiver = UNDEFINED ;
} else {
} else if ( ! IS_UNDEFINED ( receiver ) ) {
needs_wrapper = SHOULD_CREATE_WRAPPER ( f , receiver ) ;
needs_wrapper = SHOULD_CREATE_WRAPPER ( f , receiver ) ;
}
}
@ -1232,7 +1235,7 @@ function ArraySome(f, receiver) {
var element = array [ i ] ;
var element = array [ i ] ;
// Prepare break slots for debugger step in.
// Prepare break slots for debugger step in.
if ( stepping ) % DebugPrepareStepInIfStepping ( f ) ;
if ( stepping ) % DebugPrepareStepInIfStepping ( f ) ;
var new_receiver = needs_wrapper ? T oObject( receiver ) : receiver ;
var new_receiver = needs_wrapper ? $t oObject( receiver ) : receiver ;
if ( % _ CallFunction ( new_receiver , element , i , array , f ) ) return true ;
if ( % _ CallFunction ( new_receiver , element , i , array , f ) ) return true ;
}
}
}
}
@ -1245,16 +1248,14 @@ function ArrayEvery(f, receiver) {
// Pull out the length so that modifications to the length in the
// Pull out the length so that modifications to the length in the
// loop will not affect the looping and side effects are visible.
// loop will not affect the looping and side effects are visible.
var array = T oObject( this ) ;
var array = $t oObject( this ) ;
var length = TO_UINT32 ( array . length ) ;
var length = TO_UINT32 ( array . length ) ;
if ( ! IS_SPEC_FUNCTION ( f ) ) {
if ( ! IS_SPEC_FUNCTION ( f ) ) throw MakeTypeError ( kCalledNonCallable , f ) ;
throw MakeTypeError ( 'called_non_callable' , [ f ] ) ;
}
var needs_wrapper = false ;
var needs_wrapper = false ;
if ( IS_NULL_OR_UNDEFINED ( receiver ) ) {
if ( IS_NULL ( receiver ) ) {
receiver = % GetDefaultReceiver ( f ) || receiver ;
if ( % IsSloppyModeFunction ( f ) ) receiver = UNDEFINED ;
} else {
} else if ( ! IS_UNDEFINED ( receiver ) ) {
needs_wrapper = SHOULD_CREATE_WRAPPER ( f , receiver ) ;
needs_wrapper = SHOULD_CREATE_WRAPPER ( f , receiver ) ;
}
}
@ -1265,32 +1266,31 @@ function ArrayEvery(f, receiver) {
var element = array [ i ] ;
var element = array [ i ] ;
// Prepare break slots for debugger step in.
// Prepare break slots for debugger step in.
if ( stepping ) % DebugPrepareStepInIfStepping ( f ) ;
if ( stepping ) % DebugPrepareStepInIfStepping ( f ) ;
var new_receiver = needs_wrapper ? T oObject( receiver ) : receiver ;
var new_receiver = needs_wrapper ? $t oObject( receiver ) : receiver ;
if ( ! % _ CallFunction ( new_receiver , element , i , array , f ) ) return false ;
if ( ! % _ CallFunction ( new_receiver , element , i , array , f ) ) return false ;
}
}
}
}
return true ;
return true ;
}
}
function ArrayMap ( f , receiver ) {
function ArrayMap ( f , receiver ) {
CHECK_OBJECT_COERCIBLE ( this , "Array.prototype.map" ) ;
CHECK_OBJECT_COERCIBLE ( this , "Array.prototype.map" ) ;
// Pull out the length so that modifications to the length in the
// Pull out the length so that modifications to the length in the
// loop will not affect the looping and side effects are visible.
// loop will not affect the looping and side effects are visible.
var array = T oObject( this ) ;
var array = $t oObject( this ) ;
var length = TO_UINT32 ( array . length ) ;
var length = TO_UINT32 ( array . length ) ;
if ( ! IS_SPEC_FUNCTION ( f ) ) {
if ( ! IS_SPEC_FUNCTION ( f ) ) throw MakeTypeError ( kCalledNonCallable , f ) ;
throw MakeTypeError ( 'called_non_callable' , [ f ] ) ;
}
var needs_wrapper = false ;
var needs_wrapper = false ;
if ( IS_NULL_OR_UNDEFINED ( receiver ) ) {
if ( IS_NULL ( receiver ) ) {
receiver = % GetDefaultReceiver ( f ) || receiver ;
if ( % IsSloppyModeFunction ( f ) ) receiver = UNDEFINED ;
} else {
} else if ( ! IS_UNDEFINED ( receiver ) ) {
needs_wrapper = SHOULD_CREATE_WRAPPER ( f , receiver ) ;
needs_wrapper = SHOULD_CREATE_WRAPPER ( f , receiver ) ;
}
}
var result = new $ Array( ) ;
var result = new Global Array( ) ;
var accumulator = new InternalArray ( length ) ;
var accumulator = new InternalArray ( length ) ;
var is_array = IS_ARRAY ( array ) ;
var is_array = IS_ARRAY ( array ) ;
var stepping = DEBUG_IS_ACTIVE && % DebugCallbackSupportsStepping ( f ) ;
var stepping = DEBUG_IS_ACTIVE && % DebugCallbackSupportsStepping ( f ) ;
@ -1299,7 +1299,7 @@ function ArrayMap(f, receiver) {
var element = array [ i ] ;
var element = array [ i ] ;
// Prepare break slots for debugger step in.
// Prepare break slots for debugger step in.
if ( stepping ) % DebugPrepareStepInIfStepping ( f ) ;
if ( stepping ) % DebugPrepareStepInIfStepping ( f ) ;
var new_receiver = needs_wrapper ? T oObject( receiver ) : receiver ;
var new_receiver = needs_wrapper ? $t oObject( receiver ) : receiver ;
accumulator [ i ] = % _ CallFunction ( new_receiver , element , i , array , f ) ;
accumulator [ i ] = % _ CallFunction ( new_receiver , element , i , array , f ) ;
}
}
}
}
@ -1423,11 +1423,11 @@ function ArrayReduce(callback, current) {
// Pull out the length so that modifications to the length in the
// Pull out the length so that modifications to the length in the
// loop will not affect the looping and side effects are visible.
// loop will not affect the looping and side effects are visible.
var array = T oObject( this ) ;
var array = $t oObject( this ) ;
var length = T oUint32( array . length ) ;
var length = $t oUint32( array . length ) ;
if ( ! IS_SPEC_FUNCTION ( callback ) ) {
if ( ! IS_SPEC_FUNCTION ( callback ) ) {
throw MakeTypeError ( 'called_non_callable' , [ callback ] ) ;
throw MakeTypeError ( kCalledNonCallable , callback ) ;
}
}
var is_array = IS_ARRAY ( array ) ;
var is_array = IS_ARRAY ( array ) ;
@ -1439,32 +1439,32 @@ function ArrayReduce(callback, current) {
break find_initial ;
break find_initial ;
}
}
}
}
throw MakeTypeError ( 'reduce_no_initial' , [ ] ) ;
throw MakeTypeError ( kReduceNoInitial ) ;
}
}
var receiver = % GetDefaultReceiver ( callback ) ;
var stepping = DEBUG_IS_ACTIVE && % DebugCallbackSupportsStepping ( callback ) ;
var stepping = DEBUG_IS_ACTIVE && % DebugCallbackSupportsStepping ( callback ) ;
for ( ; i < length ; i ++ ) {
for ( ; i < length ; i ++ ) {
if ( HAS_INDEX ( array , i , is_array ) ) {
if ( HAS_INDEX ( array , i , is_array ) ) {
var element = array [ i ] ;
var element = array [ i ] ;
// Prepare break slots for debugger step in.
// Prepare break slots for debugger step in.
if ( stepping ) % DebugPrepareStepInIfStepping ( callback ) ;
if ( stepping ) % DebugPrepareStepInIfStepping ( callback ) ;
current = % _ CallFunction ( receiver , current , element , i , array , callback ) ;
current = % _ CallFunction ( UNDEFINED , current , element , i , array , callback ) ;
}
}
}
}
return current ;
return current ;
}
}
function ArrayReduceRight ( callback , current ) {
function ArrayReduceRight ( callback , current ) {
CHECK_OBJECT_COERCIBLE ( this , "Array.prototype.reduceRight" ) ;
CHECK_OBJECT_COERCIBLE ( this , "Array.prototype.reduceRight" ) ;
// Pull out the length so that side effects are visible before the
// Pull out the length so that side effects are visible before the
// callback function is checked.
// callback function is checked.
var array = T oObject( this ) ;
var array = $t oObject( this ) ;
var length = T oUint32( array . length ) ;
var length = $t oUint32( array . length ) ;
if ( ! IS_SPEC_FUNCTION ( callback ) ) {
if ( ! IS_SPEC_FUNCTION ( callback ) ) {
throw MakeTypeError ( 'called_non_callable' , [ callback ] ) ;
throw MakeTypeError ( kCalledNonCallable , callback ) ;
}
}
var is_array = IS_ARRAY ( array ) ;
var is_array = IS_ARRAY ( array ) ;
@ -1476,17 +1476,16 @@ function ArrayReduceRight(callback, current) {
break find_initial ;
break find_initial ;
}
}
}
}
throw MakeTypeError ( 'reduce_no_initial' , [ ] ) ;
throw MakeTypeError ( kReduceNoInitial ) ;
}
}
var receiver = % GetDefaultReceiver ( callback ) ;
var stepping = DEBUG_IS_ACTIVE && % DebugCallbackSupportsStepping ( callback ) ;
var stepping = DEBUG_IS_ACTIVE && % DebugCallbackSupportsStepping ( callback ) ;
for ( ; i >= 0 ; i -- ) {
for ( ; i >= 0 ; i -- ) {
if ( HAS_INDEX ( array , i , is_array ) ) {
if ( HAS_INDEX ( array , i , is_array ) ) {
var element = array [ i ] ;
var element = array [ i ] ;
// Prepare break slots for debugger step in.
// Prepare break slots for debugger step in.
if ( stepping ) % DebugPrepareStepInIfStepping ( callback ) ;
if ( stepping ) % DebugPrepareStepInIfStepping ( callback ) ;
current = % _ CallFunction ( receiver , current , element , i , array , callback ) ;
current = % _ CallFunction ( UNDEFINED , current , element , i , array , callback ) ;
}
}
}
}
return current ;
return current ;
@ -1500,91 +1499,100 @@ function ArrayIsArray(obj) {
// -------------------------------------------------------------------
// -------------------------------------------------------------------
function SetUpArray ( ) {
// Set up non-enumerable constructor property on the Array.prototype
% CheckIsBootstrapping ( ) ;
// object.
% AddNamedProperty ( GlobalArray . prototype , "constructor" , GlobalArray ,
// Set up non-enumerable constructor property on the Array.prototype
DONT_ENUM ) ;
// object.
% AddNamedProperty ( $Array . prototype , "constructor" , $Array , DONT_ENUM ) ;
// Set up unscopable properties on the Array.prototype object.
var unscopables = {
// Set up unscopable properties on the Array.prototype object.
__ proto__ : null ,
var unscopables = {
copyWithin : true ,
__ proto__ : null ,
entries : true ,
copyWithin : true ,
fill : true ,
entries : true ,
find : true ,
fill : true ,
findIndex : true ,
find : true ,
keys : true ,
findIndex : true ,
} ;
keys : true ,
} ;
% AddNamedProperty ( GlobalArray . prototype , symbolUnscopables , unscopables ,
% AddNamedProperty ( $Array . prototype , symbolUnscopables , unscopables ,
DONT_ENUM | READ_ONLY ) ;
DONT_ENUM | READ_ONLY ) ;
// Set up non-enumerable functions on the Array object.
// Set up non-enumerable functions on the Array object.
$installFunctions ( GlobalArray , DONT_ENUM , [
InstallFunctions ( $Array , DONT_ENUM , $Array (
"isArray" , ArrayIsArray
"isArray" , ArrayIsArray
] ) ;
) ) ;
var specialFunctions = % SpecialArrayFunctions ( ) ;
var specialFunctions = % SpecialArrayFunctions ( ) ;
var getFunction = function ( name , jsBuiltin , len ) {
var getFunction = function ( name , jsBuiltin , len ) {
var f = jsBuiltin ;
var f = jsBuiltin ;
if ( specialFunctions . hasOwnProperty ( name ) ) {
if ( specialFunctions . hasOwnProperty ( name ) ) {
f = specialFunctions [ name ] ;
f = specialFunctions [ name ] ;
}
}
if ( ! IS_UNDEFINED ( len ) ) {
if ( ! IS_UNDEFINED ( len ) ) {
% FunctionSetLength ( f , len ) ;
% FunctionSetLength ( f , len ) ;
}
}
return f ;
return f ;
} ;
} ;
// Set up non-enumerable functions of the Array.prototype object and
// Set up non-enumerable functions of the Array.prototype object and
// set their names.
// set their names.
// Manipulate the length of some of the functions to meet
// Manipulate the length of some of the functions to meet
// expectations set by ECMA-262 or Mozilla.
// expectations set by ECMA-262 or Mozilla.
$installFunctions ( GlobalArray . prototype , DONT_ENUM , [
InstallFunctions ( $Array . prototype , DONT_ENUM , $Array (
"toString" , getFunction ( "toString" , ArrayToString ) ,
"toString" , getFunction ( "toString" , ArrayToString ) ,
"toLocaleString" , getFunction ( "toLocaleString" , ArrayToLocaleString ) ,
"toLocaleString" , getFunction ( "toLocaleString" , ArrayToLocaleString ) ,
"join" , getFunction ( "join" , ArrayJoin ) ,
"join" , getFunction ( "join" , ArrayJoin ) ,
"pop" , getFunction ( "pop" , ArrayPop ) ,
"pop" , getFunction ( "pop" , ArrayPop ) ,
"push" , getFunction ( "push" , ArrayPush , 1 ) ,
"push" , getFunction ( "push" , ArrayPush , 1 ) ,
"concat" , getFunction ( "concat" , ArrayConcatJS , 1 ) ,
"concat" , getFunction ( "concat" , ArrayConcatJS , 1 ) ,
"reverse" , getFunction ( "reverse" , ArrayReverse ) ,
"reverse" , getFunction ( "reverse" , ArrayReverse ) ,
"shift" , getFunction ( "shift" , ArrayShift ) ,
"shift" , getFunction ( "shift" , ArrayShift ) ,
"unshift" , getFunction ( "unshift" , ArrayUnshift , 1 ) ,
"unshift" , getFunction ( "unshift" , ArrayUnshift , 1 ) ,
"slice" , getFunction ( "slice" , ArraySlice , 2 ) ,
"slice" , getFunction ( "slice" , ArraySlice , 2 ) ,
"splice" , getFunction ( "splice" , ArraySplice , 2 ) ,
"splice" , getFunction ( "splice" , ArraySplice , 2 ) ,
"sort" , getFunction ( "sort" , ArraySort ) ,
"sort" , getFunction ( "sort" , ArraySort ) ,
"filter" , getFunction ( "filter" , ArrayFilter , 1 ) ,
"filter" , getFunction ( "filter" , ArrayFilter , 1 ) ,
"forEach" , getFunction ( "forEach" , ArrayForEach , 1 ) ,
"forEach" , getFunction ( "forEach" , ArrayForEach , 1 ) ,
"some" , getFunction ( "some" , ArraySome , 1 ) ,
"some" , getFunction ( "some" , ArraySome , 1 ) ,
"every" , getFunction ( "every" , ArrayEvery , 1 ) ,
"every" , getFunction ( "every" , ArrayEvery , 1 ) ,
"map" , getFunction ( "map" , ArrayMap , 1 ) ,
"map" , getFunction ( "map" , ArrayMap , 1 ) ,
"indexOf" , getFunction ( "indexOf" , ArrayIndexOf , 1 ) ,
"indexOf" , getFunction ( "indexOf" , ArrayIndexOf , 1 ) ,
"lastIndexOf" , getFunction ( "lastIndexOf" , ArrayLastIndexOf , 1 ) ,
"lastIndexOf" , getFunction ( "lastIndexOf" , ArrayLastIndexOf , 1 ) ,
"reduce" , getFunction ( "reduce" , ArrayReduce , 1 ) ,
"reduce" , getFunction ( "reduce" , ArrayReduce , 1 ) ,
"reduceRight" , getFunction ( "reduceRight" , ArrayReduceRight , 1 )
"reduceRight" , getFunction ( "reduceRight" , ArrayReduceRight , 1 )
] ) ;
) ) ;
% FinishArrayPrototypeSetup ( GlobalArray . prototype ) ;
% FinishArrayPrototypeSetup ( $Array . prototype ) ;
// The internal Array prototype doesn't need to be fancy, since it's never
// The internal Array prototype doesn't need to be fancy, since it's never
// exposed to user code.
// exposed to user code.
// Adding only the functions that are actually used.
// Adding only the functions that are actually used.
$setUpLockedPrototype ( InternalArray , GlobalArray ( ) , [
SetUpLockedPrototype ( InternalArray , $Array ( ) , $Array (
"concat" , getFunction ( "concat" , ArrayConcatJS ) ,
"concat" , getFunction ( "concat" , ArrayConcatJS ) ,
"indexOf" , getFunction ( "indexOf" , ArrayIndexOf ) ,
"indexOf" , getFunction ( "indexOf" , ArrayIndexOf ) ,
"join" , getFunction ( "join" , ArrayJoin ) ,
"join" , getFunction ( "join" , ArrayJoin ) ,
"pop" , getFunction ( "pop" , ArrayPop ) ,
"pop" , getFunction ( "pop" , ArrayPop ) ,
"push" , getFunction ( "push" , ArrayPush ) ,
"push" , getFunction ( "push" , ArrayPush ) ,
"shift" , getFunction ( "shift" , ArrayShift ) ,
"splice" , getFunction ( "splice" , ArraySplice )
"splice" , getFunction ( "splice" , ArraySplice )
) ) ;
] ) ;
SetUpLockedPrototype ( InternalPackedArray , $Array ( ) , $Array (
$setUpLockedPrototype ( InternalPackedArray , GlobalArray ( ) , [
"join" , getFunction ( "join" , ArrayJoin ) ,
"join" , getFunction ( "join" , ArrayJoin ) ,
"pop" , getFunction ( "pop" , ArrayPop ) ,
"pop" , getFunction ( "pop" , ArrayPop ) ,
"push" , getFunction ( "push" , ArrayPush )
"push" , getFunction ( "push" , ArrayPush ) ,
) ) ;
"shift" , getFunction ( "shift" , ArrayShift )
}
] ) ;
SetUpArray ( ) ;
$arrayConcat = ArrayConcatJS ;
$arrayJoin = ArrayJoin ;
$arrayPush = ArrayPush ;
$arrayPop = ArrayPop ;
$arrayShift = ArrayShift ;
$arraySlice = ArraySlice ;
$arraySplice = ArraySplice ;
$arrayUnshift = ArrayUnshift ;
} )