Ticket #622: js-upgrade-wip.diff

File js-upgrade-wip.diff, 142.1 KB (added by Philip Taylor, 14 years ago)
  • binaries/data/mods/_test.sim/simulation/components/test-entityid.js

    diff -r 6b3ac7e864ba binaries/data/mods/_test.sim/simulation/components/test-entityid.js
    a b  
    22
    33TestScript1A.prototype.GetX = function() {
    44    // Test that .entity is readonly
    5     delete this.entity;
    6     this.entity = -1;
     5    try {
     6        delete this.entity;
     7        Engine.TS_FAIL("Missed exception");
     8    } catch (e) { }
     9    try {
     10        this.entity = -1;
     11        Engine.TS_FAIL("Missed exception");
     12    } catch (e) { }
    713   
    814    // and return the value
    915    return this.entity;
  • binaries/data/mods/_test.sim/simulation/components/test-serialize.js

    diff -r 6b3ac7e864ba binaries/data/mods/_test.sim/simulation/components/test-serialize.js
    a b  
    1919
    2020TestScript1_entity.prototype.GetX = function() {
    2121    // Test that .entity is readonly
    22     delete this.entity;
    23     this.entity = -1;
     22    try {
     23        delete this.entity;
     24        Engine.TS_FAIL("Missed exception");
     25    } catch (e) { }
     26    try {
     27        this.entity = -1;
     28        Engine.TS_FAIL("Missed exception");
     29    } catch (e) { }
    2430
    2531    // and return the value
    2632    return this.entity;
  • deleted file source/graphics/scripting/JSInterface_Camera.cpp

    diff -r 6b3ac7e864ba source/graphics/scripting/JSInterface_Camera.cpp
    + -  
    1 /* Copyright (C) 2009 Wildfire Games.
    2  * This file is part of 0 A.D.
    3  *
    4  * 0 A.D. is free software: you can redistribute it and/or modify
    5  * it under the terms of the GNU General Public License as published by
    6  * the Free Software Foundation, either version 2 of the License, or
    7  * (at your option) any later version.
    8  *
    9  * 0 A.D. is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
    16  */
    17 
    18 #include "precompiled.h"
    19 
    20 #include "JSInterface_Camera.h"
    21 
    22 #include "scripting/JSConversions.h"
    23 #include "maths/scripting/JSInterface_Vector3D.h"
    24 #include "graphics/Camera.h"
    25 #include "maths/Vector3D.h"
    26 #include "maths/Matrix3D.h"
    27 #include "maths/MathUtil.h"
    28 #include "graphics/Terrain.h"
    29 #include "ps/Game.h"
    30 #include "graphics/GameView.h"
    31 
    32 
    33 JSClass JSI_Camera::JSI_class = {
    34     "Camera", JSCLASS_HAS_PRIVATE,
    35     JS_PropertyStub, JS_PropertyStub,
    36     JSI_Camera::getProperty, JSI_Camera::setProperty,
    37     JS_EnumerateStub, JS_ResolveStub,
    38     JS_ConvertStub, JSI_Camera::finalize,
    39     NULL, NULL, NULL, NULL
    40 };
    41 
    42 JSPropertySpec JSI_Camera::JSI_props[] =
    43 {
    44     { "position", JSI_Camera::vector_position, JSPROP_ENUMERATE },
    45     { "orientation", JSI_Camera::vector_orientation, JSPROP_ENUMERATE },
    46     { "up", JSI_Camera::vector_up, JSPROP_ENUMERATE },
    47     { 0 },
    48 };
    49 
    50 JSFunctionSpec JSI_Camera::JSI_methods[] =
    51 {
    52     { "lookAt", JSI_Camera::lookAt, 2, 0, 0 },
    53     { "getFocus", JSI_Camera::getFocus, 0, 0, 0 },
    54     { 0 }
    55 };
    56 
    57 void JSI_Camera::init()
    58 {
    59     g_ScriptingHost.DefineCustomObjectType( &JSI_class, JSI_Camera::construct, 0, JSI_props, JSI_methods, NULL, NULL );
    60 }
    61 
    62 JSI_Camera::Camera_Info::Camera_Info()
    63 {
    64     Initialise();
    65 }
    66 
    67 JSI_Camera::Camera_Info::Camera_Info( const CVector3D& Position )
    68 {
    69     CMatrix3D Orient;
    70     Orient.SetXRotation( DEGTORAD( 30 ) );
    71     Orient.RotateY( DEGTORAD( -45 ) );
    72     Orient.Translate( Position );
    73 
    74     Initialise( (const CMatrix3D&)Orient );
    75 }
    76 
    77 JSI_Camera::Camera_Info::Camera_Info( const CVector3D& Position, const CVector3D& Orientation )
    78 {
    79     Initialise();
    80     m_Data->LookAlong( Position, Orientation, CVector3D( 0.0f, 1.0f, 0.0f ) );
    81 }
    82 
    83 JSI_Camera::Camera_Info::Camera_Info( const CVector3D& Position, const CVector3D& Orientation, const CVector3D& Up )
    84 {
    85     Initialise();
    86     m_Data->LookAlong( Position, Orientation, Up );
    87 }
    88 
    89 JSI_Camera::Camera_Info::Camera_Info( const CMatrix3D& Orientation )
    90 {
    91     Initialise( Orientation );
    92 }
    93 
    94 JSI_Camera::Camera_Info::Camera_Info( CCamera* Reference )
    95 {
    96     m_Data = Reference;
    97     m_EngineOwned = true;
    98 }
    99 
    100 JSI_Camera::Camera_Info::~Camera_Info()
    101 {
    102     if( !m_EngineOwned )
    103         delete( m_Data );
    104 }
    105 
    106 void JSI_Camera::Camera_Info::Initialise()
    107 {
    108     CMatrix3D Orient;
    109     Orient.SetXRotation( DEGTORAD( 30 ) );
    110     Orient.RotateY( DEGTORAD( -45 ) );
    111     Orient.Translate( 100, 150, -100 );
    112 
    113     Initialise( (const CMatrix3D&)Orient );
    114 }
    115 
    116 void JSI_Camera::Camera_Info::Initialise( const CMatrix3D& Orientation )
    117 {
    118     m_Data = new CCamera();
    119     m_EngineOwned = false;
    120 
    121     m_Data->LookAlong( Orientation.GetTranslation(), Orientation.GetIn(), Orientation.GetUp() );
    122 }
    123 
    124 void JSI_Camera::Camera_Info::Freshen()
    125 {
    126     m_sv_Position = m_Data->m_Orientation.GetTranslation();
    127     m_sv_Orientation = m_Data->m_Orientation.GetIn();
    128     m_sv_Up = m_Data->m_Orientation.GetUp();
    129 }
    130 
    131 void JSI_Camera::Camera_Info::Update()
    132 {
    133     m_Data->LookAlong( m_sv_Position, m_sv_Orientation, m_sv_Up );
    134 }
    135 
    136 void JSI_Camera::Camera_Info::FreshenTarget()
    137 {
    138     m_sv_Target = m_Data->GetFocus();
    139 }
    140 
    141 JSBool JSI_Camera::getCamera( JSContext* cx, JSObject* UNUSED(obj), jsval UNUSED(id), jsval* vp )
    142 {
    143     if( g_Game && g_Game->GetView()->GetCamera() )
    144     {
    145         JSObject* camera = JS_NewObject( cx, &JSI_Camera::JSI_class, NULL, NULL );
    146         JS_SetPrivate( cx, camera, new Camera_Info( g_Game->GetView()->GetCamera() ) );
    147         *vp = OBJECT_TO_JSVAL( camera );
    148     }
    149     else
    150     {
    151         *vp = JSVAL_NULL;
    152     }
    153     return( JS_TRUE );
    154 }
    155 
    156 JSBool JSI_Camera::setCamera( JSContext* cx, JSObject* UNUSED(obj), jsval UNUSED(id), jsval* vp )
    157 {
    158     JSObject* camera = JSVAL_TO_OBJECT( *vp );
    159     Camera_Info* cameraInfo;
    160     if( !JSVAL_IS_OBJECT( *vp ) || NULL == ( cameraInfo = (Camera_Info*)JS_GetInstancePrivate( cx, camera, &JSI_Camera::JSI_class, NULL ) ) )
    161     {
    162         JS_ReportError( cx, "[Camera] Invalid object" );
    163     }
    164     else
    165     {
    166         g_Game->GetView()->GetCamera()->m_Orientation = cameraInfo->m_Data->m_Orientation;
    167     }
    168     return( JS_TRUE );
    169 }
    170 
    171 JSBool JSI_Camera::getProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp )
    172 {
    173     if( !JSVAL_IS_INT( id ) )
    174         return( JS_TRUE );
    175 
    176     Camera_Info* cameraInfo = (Camera_Info*)JS_GetPrivate( cx, obj );
    177     if( !cameraInfo )
    178     {
    179         JS_ReportError( cx, "[Camera] Invalid Reference" );
    180         return( JS_TRUE );
    181     }
    182    
    183     CVector3D* d;
    184 
    185     switch( ToPrimitive<int>( id ) )
    186     {
    187     case vector_position: d = &cameraInfo->m_sv_Position; break;
    188     case vector_orientation: d = &cameraInfo->m_sv_Orientation; break;
    189     case vector_up: d = &cameraInfo->m_sv_Up; break;
    190     default: return( JS_TRUE );
    191     }
    192 
    193     JSObject* vector3d = JS_NewObject( g_ScriptingHost.getContext(), &JSI_Vector3D::JSI_class, NULL, NULL );
    194     JS_SetPrivate( g_ScriptingHost.getContext(), vector3d, new JSI_Vector3D::Vector3D_Info( d, cameraInfo, ( void( IPropertyOwner::* )() )&Camera_Info::Update, ( void( IPropertyOwner::* )() )&Camera_Info::Freshen ) );
    195     *vp = OBJECT_TO_JSVAL( vector3d );
    196     return( JS_TRUE );
    197 }
    198 
    199 JSBool JSI_Camera::setProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp )
    200 {
    201     if( !JSVAL_IS_INT( id ) )
    202         return( JS_TRUE );
    203 
    204     Camera_Info* cameraInfo = (Camera_Info*)JS_GetPrivate( cx, obj );
    205     if( !cameraInfo )
    206     {
    207         JS_ReportError( cx, "[Camera] Invalid reference" );
    208         return( JS_TRUE );
    209     }
    210    
    211     JSObject* vector3d = JSVAL_TO_OBJECT( *vp );
    212     JSI_Vector3D::Vector3D_Info* v = NULL;
    213 
    214     if( JSVAL_IS_OBJECT( *vp ) && NULL != ( v = (JSI_Vector3D::Vector3D_Info*)JS_GetInstancePrivate( g_ScriptingHost.getContext(), vector3d, &JSI_Vector3D::JSI_class, NULL ) ) )
    215     {
    216         cameraInfo->Freshen();
    217 
    218         switch( ToPrimitive<int>( id ) )
    219         {
    220         case vector_position: cameraInfo->m_sv_Position = *( v->vector ); break;
    221         case vector_orientation: cameraInfo->m_sv_Orientation = *( v->vector ); break;
    222         case vector_up: cameraInfo->m_sv_Up = *( v->vector ); break;
    223         }
    224 
    225         cameraInfo->Update();
    226     }
    227 
    228     return( JS_TRUE );
    229 }
    230 
    231 #define GETVECTOR( jv ) ( ( JSVAL_IS_OBJECT( jv ) && NULL != ( v = (JSI_Vector3D::Vector3D_Info*)JS_GetInstancePrivate( g_ScriptingHost.getContext(), JSVAL_TO_OBJECT( jv ), &JSI_Vector3D::JSI_class, NULL ) ) ) ? *(v->vector) : CVector3D() )
    232 
    233 
    234 JSBool JSI_Camera::lookAt( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval )
    235 {
    236     JSI_Vector3D::Vector3D_Info* v = NULL;
    237     Camera_Info* cameraInfo = (Camera_Info*)JS_GetPrivate( cx, obj );
    238 
    239     JSU_REQUIRE_PARAM_RANGE(2, 3);
    240 
    241     cameraInfo->m_sv_Position = GETVECTOR( argv[0] );
    242     cameraInfo->m_sv_Orientation = GETVECTOR( argv[1] ) - cameraInfo->m_sv_Position;
    243     cameraInfo->m_sv_Orientation.Normalize();
    244 
    245     if( argc == 2 )
    246     {
    247         cameraInfo->m_sv_Up = CVector3D( 0.0f, 1.0f, 0.0f );
    248     }
    249     else if( argc == 3 )
    250     {
    251         cameraInfo->m_sv_Up = GETVECTOR( argv[2] );
    252     }
    253 
    254     cameraInfo->Update();
    255 
    256     *rval = JSVAL_TRUE;
    257     return( JS_TRUE );
    258 }
    259 
    260 JSBool JSI_Camera::getFocus( JSContext* cx, JSObject* obj,
    261     uintN UNUSED(argc), jsval* UNUSED(argv), jsval* rval )
    262 {
    263     // Largely copied from the equivalent method in CCamera
    264 
    265     Camera_Info* cameraInfo = (Camera_Info*)JS_GetPrivate( cx, obj );
    266 
    267     JSObject* vector3d = JS_NewObject( g_ScriptingHost.getContext(), &JSI_Vector3D::JSI_class, NULL, NULL );
    268     JS_SetPrivate( g_ScriptingHost.getContext(), vector3d, new JSI_Vector3D::Vector3D_Info( &( cameraInfo->m_sv_Target ), cameraInfo, NULL, ( void( IPropertyOwner::* )() )&Camera_Info::FreshenTarget ) );
    269     *rval = OBJECT_TO_JSVAL( vector3d );
    270     return( JS_TRUE );
    271 }
    272 
    273 JSBool JSI_Camera::construct( JSContext* cx, JSObject* UNUSED(obj),
    274     uintN argc, jsval* argv, jsval* rval )
    275 {
    276     JSI_Vector3D::Vector3D_Info* v = NULL;
    277 
    278     JSObject* camera = JS_NewObject( cx, &JSI_Camera::JSI_class, NULL, NULL );
    279 
    280     JSU_REQUIRE_MAX_PARAMS(3);
    281     Camera_Info* camera_info = 0;
    282     switch(argc)
    283     {
    284     case 0:
    285         camera_info = new Camera_Info();
    286         break;
    287     case 1:
    288         camera_info = new Camera_Info( GETVECTOR( argv[0] ) );
    289         break;
    290     case 2:
    291         camera_info = new Camera_Info( GETVECTOR( argv[0] ), GETVECTOR( argv[1] ) );
    292         break;
    293     case 3:
    294         camera_info = new Camera_Info( GETVECTOR( argv[0] ), GETVECTOR( argv[1] ), GETVECTOR( argv[2] ) );
    295         break;
    296     NODEFAULT;
    297     }
    298 
    299 #undef GET_VECTOR
    300 
    301     JS_SetPrivate( cx, camera, camera_info );
    302     *rval = OBJECT_TO_JSVAL( camera );
    303     return( JS_TRUE );
    304 }
    305 
    306 void JSI_Camera::finalize( JSContext* cx, JSObject* obj )
    307 {
    308     delete( (Camera_Info*)JS_GetPrivate( cx, obj ) );
    309 }
    310 
  • deleted file source/graphics/scripting/JSInterface_Camera.h

    diff -r 6b3ac7e864ba source/graphics/scripting/JSInterface_Camera.h
    + -  
    1 /* Copyright (C) 2009 Wildfire Games.
    2  * This file is part of 0 A.D.
    3  *
    4  * 0 A.D. is free software: you can redistribute it and/or modify
    5  * it under the terms of the GNU General Public License as published by
    6  * the Free Software Foundation, either version 2 of the License, or
    7  * (at your option) any later version.
    8  *
    9  * 0 A.D. is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
    16  */
    17 
    18 // JSInterface_Camera.h
    19 //
    20 // A JavaScript wrapper around a camera object.
    21 //
    22 // Usage: When manipulating objects of type 'Camera' in JavaScript
    23 
    24 #include "scripting/ScriptingHost.h"
    25 
    26 #include "maths/Vector3D.h"
    27 #include "graphics/Camera.h"
    28 #include "graphics/HFTracer.h"
    29 
    30 #ifndef INCLUDED_JSI_CAMERA
    31 #define INCLUDED_JSI_CAMERA
    32 
    33 namespace JSI_Camera
    34 {
    35     enum
    36     {
    37         vector_position,
    38         vector_orientation,
    39         vector_up
    40     };
    41 
    42     enum
    43     {
    44         lookat
    45     };
    46 
    47     struct Camera_Info : public IPropertyOwner
    48     {
    49         CCamera* m_Data;
    50         bool m_EngineOwned;
    51         CVector3D m_sv_Position;
    52         CVector3D m_sv_Orientation;
    53         CVector3D m_sv_Up;
    54         CVector3D m_sv_Target;
    55 
    56         Camera_Info(); // Create a camera set to the initial view
    57 
    58         Camera_Info( const CVector3D& Position );
    59         Camera_Info( const CVector3D& Position, const CVector3D& Orientation );
    60         Camera_Info( const CVector3D& Position, const CVector3D& Orientation, const CVector3D& Up );
    61         Camera_Info( const CMatrix3D& Orientation );
    62         Camera_Info( CCamera* copy );
    63 
    64         void Initialise();
    65         void Initialise( const CMatrix3D& Orientation );
    66 
    67         void Freshen();
    68         void Update();
    69         void FreshenTarget();
    70 
    71         ~Camera_Info();
    72 /*
    73 
    74         Camera_Info( const CVector3D& _position );
    75         Camera_Info( const CVector3D& _position, const CVector3D& _orientation );
    76         Camera_Info( const CVector3D& _position, const CVector3D& _orientation, const CVector3D& _up );
    77         Camera_Info( CCamera* _copy );
    78         void update();
    79 
    80 */
    81     };
    82     extern JSClass JSI_class;
    83     extern JSPropertySpec JSI_props[];
    84     extern JSFunctionSpec JSI_methods[];
    85 
    86     JSBool getProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp );
    87     JSBool setProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp );
    88 
    89     JSBool getCamera( JSContext* cx, JSObject* obj, jsval id, jsval* vp );
    90     JSBool setCamera( JSContext* cx, JSObject* obj, jsval id, jsval* vp );
    91 
    92     JSBool construct( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );
    93     void finalize( JSContext* cx, JSObject* obj );
    94 
    95     JSBool lookAt( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );
    96     JSBool getFocus( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );
    97 
    98     void init();
    99 }
    100 
    101 #endif
  • deleted file source/graphics/scripting/JSInterface_LightEnv.cpp

    diff -r 6b3ac7e864ba source/graphics/scripting/JSInterface_LightEnv.cpp
    + -  
    1 /* Copyright (C) 2009 Wildfire Games.
    2  * This file is part of 0 A.D.
    3  *
    4  * 0 A.D. is free software: you can redistribute it and/or modify
    5  * it under the terms of the GNU General Public License as published by
    6  * the Free Software Foundation, either version 2 of the License, or
    7  * (at your option) any later version.
    8  *
    9  * 0 A.D. is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
    16  */
    17 
    18 /*
    19  * Provide the LightEnv object type for JavaScript
    20  */
    21 
    22 #include "precompiled.h"
    23 
    24 #include "maths/scripting/JSInterface_Vector3D.h"
    25 
    26 #include "graphics/scripting/JSInterface_LightEnv.h"
    27 #include "graphics/LightEnv.h"
    28 
    29 #include "ps/World.h"
    30 
    31 #include "scripting/JSConversions.h"
    32 
    33 
    34 namespace JSI_LightEnv {
    35 
    36 namespace {
    37 
    38 extern JSClass JSI_class;
    39 
    40 /**
    41  * This enumeration is used to index properties with the JavaScript implementation.
    42  */
    43 enum
    44 {
    45     lightenv_elevation,
    46     lightenv_rotation,
    47     lightenv_terrainShadowTransparency,
    48     lightenv_sun,
    49     lightenv_terrainAmbient,
    50     lightenv_unitsAmbient
    51 };
    52 
    53 ///////////////////////////////////////////////////////////////////////////////////////////////
    54 // LightEnv_Info, the private structure that holds data for individual LightEnv objects
    55 
    56 struct LightEnv_Info : public IPropertyOwner
    57 {
    58     CLightEnv* m_Data;
    59     bool m_EngineOwned;
    60 
    61     // Create a new LightEnv that will only be used by JavaScript
    62     LightEnv_Info()
    63     {
    64         m_Data = new CLightEnv;
    65         m_EngineOwned = false;
    66     }
    67 
    68     // Use the given CLightEnv from the engine. The caller must guarantee that
    69     // the copy object will not be deleted.
    70     LightEnv_Info(CLightEnv* copy)
    71     {
    72         m_Data = copy;
    73         m_EngineOwned = true;
    74     }
    75 
    76     ~LightEnv_Info()
    77     {
    78         if (!m_EngineOwned)
    79             delete m_Data;
    80     }
    81 };
    82 
    83 
    84 ///////////////////////////////////////////////////////////////////////////////////////////////
    85 // Construction and finalization of LightEnvs
    86 
    87 /**
    88  * construct: the LightEnv constructor has been called from JavaScript, so create a new
    89  * LightEnv object
    90  */
    91 JSBool construct(JSContext* cx, JSObject* UNUSED(obj), uintN argc, jsval* argv, jsval* rval)
    92 {
    93     JSObject* lightenv = JS_NewObject(cx, &JSI_class, NULL, NULL);
    94 
    95     JSU_REQUIRE_NO_PARAMS();
    96 
    97     JS_SetPrivate(cx, lightenv, new LightEnv_Info);
    98     *rval = OBJECT_TO_JSVAL(lightenv);
    99     return JS_TRUE;
    100 }
    101 
    102 /**
    103  * finalize: callback from the JS engine to indicate we should free our private data
    104  */
    105 void finalize(JSContext* cx, JSObject* obj)
    106 {
    107     delete (LightEnv_Info*)JS_GetPrivate(cx, obj);
    108 }
    109 
    110 
    111 ///////////////////////////////////////////////////////////////////////////////////////////////
    112 // Accessing properties of a LightEnv object
    113 
    114 // Can't use ToJSVal here because we need live updates from the vectors
    115 JSBool getVectorProperty(JSContext* cx, LightEnv_Info* lightenvInfo, CVector3D* vec, jsval* vp)
    116 {
    117     JSObject* vector3d = JS_NewObject(cx, &JSI_Vector3D::JSI_class, NULL, NULL);
    118     JS_SetPrivate(cx, vector3d, new JSI_Vector3D::Vector3D_Info(vec, lightenvInfo));
    119     *vp = OBJECT_TO_JSVAL(vector3d);
    120     return JS_TRUE;
    121 }
    122 
    123 
    124 JSBool getProperty(JSContext* cx, JSObject* obj, jsval id, jsval* vp)
    125 {
    126     if (!JSVAL_IS_INT(id))
    127         return JS_TRUE ;
    128 
    129     LightEnv_Info* lightenvInfo = (LightEnv_Info*)JS_GetPrivate(cx, obj);
    130     if (!lightenvInfo)
    131     {
    132         JS_ReportError(cx, "[LightEnv] Invalid Reference");
    133         return JS_TRUE;
    134     }
    135 
    136     CLightEnv* lightenv = lightenvInfo->m_Data;
    137 
    138     switch(ToPrimitive<int>(id)) {
    139     case lightenv_elevation: *vp = ToJSVal(lightenv->GetElevation()); break;
    140     case lightenv_rotation: *vp = ToJSVal(lightenv->GetRotation()); break;
    141     case lightenv_terrainShadowTransparency: *vp = ToJSVal(lightenv->GetTerrainShadowTransparency()); break;
    142     case lightenv_sun: return getVectorProperty(cx, lightenvInfo, &lightenv->m_SunColor, vp);
    143     case lightenv_terrainAmbient: return getVectorProperty(cx, lightenvInfo, &lightenv->m_TerrainAmbientColor, vp);
    144     case lightenv_unitsAmbient: return getVectorProperty(cx, lightenvInfo, &lightenv->m_UnitsAmbientColor, vp);
    145     default: break;
    146     }
    147 
    148     return JS_TRUE;
    149 }
    150 
    151 
    152 JSBool setProperty(JSContext* cx, JSObject* obj, jsval id, jsval* vp)
    153 {
    154     if (!JSVAL_IS_INT(id))
    155         return( JS_TRUE );
    156 
    157     LightEnv_Info* lightenvInfo = (LightEnv_Info*)JS_GetPrivate(cx, obj);
    158     if (!lightenvInfo)
    159     {
    160         JS_ReportError(cx, "[LightEnv] Invalid reference");
    161         return JS_TRUE;
    162     }
    163 
    164     CLightEnv* lightenv = lightenvInfo->m_Data;
    165 
    166     switch(ToPrimitive<int>(id)) {
    167     case lightenv_elevation: lightenv->SetElevation(ToPrimitive<float>(*vp)); break;
    168     case lightenv_rotation: lightenv->SetRotation(ToPrimitive<float>(*vp)); break;
    169     case lightenv_terrainShadowTransparency: lightenv->SetTerrainShadowTransparency(ToPrimitive<float>(*vp)); break;
    170     case lightenv_sun: lightenv->m_SunColor = ToPrimitive<CVector3D>(*vp); break;
    171     case lightenv_terrainAmbient: lightenv->m_TerrainAmbientColor = ToPrimitive<CVector3D>(*vp); break;
    172     case lightenv_unitsAmbient: lightenv->m_UnitsAmbientColor = ToPrimitive<CVector3D>(*vp); break;
    173     default: break;
    174     }
    175 
    176     return JS_TRUE;
    177 }
    178 
    179 
    180 
    181 ///////////////////////////////////////////////////////////////////////////////////////////////
    182 // Registration of LightEnv class with JavaScript
    183 
    184 JSClass JSI_class = {
    185     "LightEnv", JSCLASS_HAS_PRIVATE,
    186     JS_PropertyStub, JS_PropertyStub,
    187     getProperty, setProperty,
    188     JS_EnumerateStub, JS_ResolveStub,
    189     JS_ConvertStub, finalize,
    190     NULL, NULL, NULL, NULL
    191 };
    192 
    193 JSPropertySpec JSI_props[] =
    194 {
    195     { "elevation", lightenv_elevation, JSPROP_ENUMERATE },
    196     { "rotation", lightenv_rotation, JSPROP_ENUMERATE },
    197     { "terrainShadowTransparency", lightenv_terrainShadowTransparency, JSPROP_ENUMERATE },
    198     { "sun", lightenv_sun, JSPROP_ENUMERATE },
    199     { "terrainAmbient", lightenv_terrainAmbient, JSPROP_ENUMERATE },
    200     { "unitsAmbient", lightenv_unitsAmbient, JSPROP_ENUMERATE },
    201     { 0 },
    202 };
    203 
    204 JSFunctionSpec JSI_methods[] =
    205 {
    206     { 0 }
    207 };
    208 
    209 } // anonymous namespace
    210 
    211 /**
    212  * init: called by GameSetup to register the LightEnv class with the JS engine.
    213  */
    214 void init()
    215 {
    216     g_ScriptingHost.DefineCustomObjectType( &JSI_class, construct, 0, JSI_props, JSI_methods, NULL, NULL );
    217 }
    218 
    219 
    220 ///////////////////////////////////////////////////////////////////////////////////////////////
    221 // Accessing the global lightenv
    222 
    223 JSBool getLightEnv(JSContext* cx, JSObject* UNUSED(obj), jsval UNUSED(id), jsval* vp)
    224 {
    225     JSObject* lightenv = JS_NewObject(cx, &JSI_class, NULL, NULL);
    226     JS_SetPrivate(cx, lightenv, new LightEnv_Info(&g_LightEnv));
    227     *vp = OBJECT_TO_JSVAL(lightenv);
    228     return JS_TRUE;
    229 }
    230 
    231 JSBool setLightEnv(JSContext* cx, JSObject* UNUSED(obj), jsval UNUSED(id), jsval* vp)
    232 {
    233     JSObject* lightenv = JSVAL_TO_OBJECT(*vp);
    234     LightEnv_Info* lightenvInfo;
    235 
    236     if (!JSVAL_IS_OBJECT(*vp) || NULL == (lightenvInfo = (LightEnv_Info*)JS_GetInstancePrivate(cx, lightenv, &JSI_class, NULL)))
    237     {
    238         JS_ReportError( cx, "[LightEnv] Invalid object" );
    239     }
    240     else
    241     {
    242         g_LightEnv = *lightenvInfo->m_Data;
    243     }
    244 
    245     return JS_TRUE;
    246 }
    247 
    248 } // namespace JSI_LightEnv
    249 
    250 
  • deleted file source/graphics/scripting/JSInterface_LightEnv.h

    diff -r 6b3ac7e864ba source/graphics/scripting/JSInterface_LightEnv.h
    + -  
    1 /* Copyright (C) 2009 Wildfire Games.
    2  * This file is part of 0 A.D.
    3  *
    4  * 0 A.D. is free software: you can redistribute it and/or modify
    5  * it under the terms of the GNU General Public License as published by
    6  * the Free Software Foundation, either version 2 of the License, or
    7  * (at your option) any later version.
    8  *
    9  * 0 A.D. is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
    16  */
    17 
    18 /*
    19  * Provide the LightEnv object type for JavaScript
    20  */
    21 
    22 #ifndef INCLUDED_JSI_LIGHTENV
    23 #define INCLUDED_JSI_LIGHTENV
    24 
    25 #include "scripting/ScriptingHost.h"
    26 
    27 namespace JSI_LightEnv
    28 {
    29     void init();
    30     JSBool getLightEnv( JSContext* cx, JSObject* obj, jsval id, jsval* vp );
    31     JSBool setLightEnv( JSContext* cx, JSObject* obj, jsval id, jsval* vp );
    32 }
    33 
    34 #endif
  • source/gui/CGUI.cpp

    diff -r 6b3ac7e864ba source/gui/CGUI.cpp
    a b  
    326326        &IGUIObject::ScriptEvent, EventName.LowerCase());
    327327}
    328328
     329
     330// Class needed for constructor
     331static JSClass global_class = {
     332    "global", JSCLASS_GLOBAL_FLAGS,
     333    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
     334    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
     335    NULL, NULL, NULL, NULL,
     336    NULL, NULL, NULL, NULL
     337};
     338
    329339//-------------------------------------------------------------------
    330340//  Constructor / Destructor
    331341//-------------------------------------------------------------------
     
    334344    m_BaseObject = new CGUIDummyObject;
    335345    m_BaseObject->SetGUI(this);
    336346
    337     // Construct the parent object for all GUI JavaScript things
    338     m_ScriptObject = JS_NewObject(g_ScriptingHost.getContext(), NULL, g_ScriptingHost.GetGlobalObject(), NULL);
    339     debug_assert(m_ScriptObject != NULL); // How should it handle errors?
    340     JS_AddRoot(g_ScriptingHost.getContext(), &m_ScriptObject);
     347    // Construct the root object for all GUI JavaScript things
     348    // (We need an object with no parent, so functions defined by scripts get
     349    // put onto this object and not its parent. In the current version of SpiderMonkey
     350    // that means it must be a global object. Then we adjust its prototype so it
     351    // can still read standard properties from the context's standard global object.)
     352    m_ScriptObject = JS_NewGlobalObject(g_ScriptingHost.getContext(), &global_class);
     353    JS_AddObjectRoot(g_ScriptingHost.getContext(), &m_ScriptObject);
     354
     355    JS_SetPrototype(g_ScriptingHost.getContext(), m_ScriptObject, g_ScriptingHost.GetGlobalObject());
    341356}
    342357
    343358CGUI::~CGUI()
     
    350365    if (m_ScriptObject)
    351366    {
    352367        // Let it be garbage-collected
    353         JS_RemoveRoot(g_ScriptingHost.getContext(), &m_ScriptObject);
     368        JS_RemoveObjectRoot(g_ScriptingHost.getContext(), &m_ScriptObject);
    354369    }
    355370}
    356371
  • source/gui/GUIManager.cpp

    diff -r 6b3ac7e864ba source/gui/GUIManager.cpp
    a b  
    4848    return g_GUI->HandleEvent(ev);
    4949}
    5050
    51 CGUIManager::SGUIPage::SGUIPage()
    52 {
    53     JS_AddNamedRoot(g_ScriptingHost.GetContext(), &initData, "SGUIPage initData");
    54 }
    55 
    56 CGUIManager::SGUIPage::SGUIPage(const SGUIPage& page)
    57 {
    58     *this = page;
    59     JS_AddNamedRoot(g_ScriptingHost.GetContext(), &initData, "SGUIPage initData copy");
    60 }
    61 
    62 CGUIManager::SGUIPage::~SGUIPage()
    63 {
    64     JS_RemoveRoot(g_ScriptingHost.GetContext(), &initData);
    65 }
    66 
    6751CGUIManager::CGUIManager(ScriptInterface& scriptInterface) :
    6852    m_ScriptInterface(scriptInterface)
    6953{
     
    9074{
    9175    m_PageStack.push_back(SGUIPage());
    9276    m_PageStack.back().name = pageName;
    93     m_PageStack.back().initData = initData;
     77    m_PageStack.back().initData = CScriptValRooted(m_ScriptInterface.GetContext(), initData);
    9478    LoadPage(m_PageStack.back());
    9579}
    9680
  • source/gui/GUIManager.h

    diff -r 6b3ac7e864ba source/gui/GUIManager.h
    a b  
    135135private:
    136136    struct SGUIPage
    137137    {
    138         SGUIPage();
    139         SGUIPage(const SGUIPage&);
    140         ~SGUIPage();
    141 
    142138        CStrW name;
    143139        std::set<VfsPath> inputs; // for hotloading
    144140
    145141        JSContext* cx;
    146         CScriptVal initData; // data to be passed to the init() function
     142        CScriptValRooted initData; // data to be passed to the init() function
    147143
    148144        shared_ptr<CGUI> gui; // the actual GUI page
    149145    };
  • source/gui/IGUIObject.cpp

    diff -r 6b3ac7e864ba source/gui/IGUIObject.cpp
    a b  
    9090        std::map<CStr, JSObject**>::iterator it;
    9191        for (it = m_ScriptHandlers.begin(); it != m_ScriptHandlers.end(); ++it)
    9292        {
    93             JS_RemoveRoot(g_ScriptingHost.getContext(), it->second);
     93            JS_RemoveObjectRoot(g_ScriptingHost.getContext(), it->second);
    9494            delete it->second;
    9595        }
    9696    }
    9797   
    9898    if (m_JSObject)
    99         JS_RemoveRoot(g_ScriptingHost.getContext(), &m_JSObject);
     99        JS_RemoveObjectRoot(g_ScriptingHost.getContext(), &m_JSObject);
    100100}
    101101
    102102//-------------------------------------------------------------------
     
    488488{
    489489    JSObject** obj = new JSObject*;
    490490    *obj = Function;
    491     JS_AddRoot(g_ScriptingHost.getContext(), obj);
     491    JS_AddObjectRoot(g_ScriptingHost.getContext(), obj);
    492492
    493493    if (m_ScriptHandlers[Action])
    494494    {
    495         JS_RemoveRoot(g_ScriptingHost.getContext(), m_ScriptHandlers[Action]);
     495        JS_RemoveObjectRoot(g_ScriptingHost.getContext(), m_ScriptHandlers[Action]);
    496496        delete m_ScriptHandlers[Action];
    497497    }
    498498    m_ScriptHandlers[Action] = obj;
     
    504504    if (it == m_ScriptHandlers.end())
    505505        return;
    506506
    507     // PRIVATE_TO_JSVAL assumes two-byte alignment,
    508     // so make sure that's always true
    509     debug_assert(! ((jsval)this & JSVAL_INT));
    510 
    511507    // The IGUIObject needs to be stored inside the script's object
    512508    jsval guiObject = PRIVATE_TO_JSVAL(this);
    513509
     
    517513   
    518514    // TODO: why don't we use GetJSObject here?
    519515
    520     // Prevent it from being garbage-collected before it's passed into the function
    521     JS_AddRoot(g_ScriptingHost.getContext(), &jsGuiObject);
    522 
    523516    // Set up the 'mouse' parameter
    524517    jsval mouseParams[3];
    525518    mouseParams[0] = INT_TO_JSVAL(m_pGUI->m_MousePos.x);
     
    528521    JSObject* mouseObj = JS_ConstructObjectWithArguments(g_ScriptingHost.getContext(), &JSI_GUIMouse::JSI_class, m_pGUI->m_ScriptObject, NULL, 3, mouseParams);
    529522    debug_assert(mouseObj); // TODO: Handle errors
    530523
    531     // Don't garbage collect the mouse
    532     JS_AddRoot(g_ScriptingHost.getContext(), &mouseObj);
    533 
    534524    jsval paramData[] = { OBJECT_TO_JSVAL(mouseObj) };
    535525
    536526    jsval result;
     
    539529    {
    540530        JS_ReportError(g_ScriptingHost.getContext(), "Errors executing script action \"%s\"", Action.c_str());
    541531    }
    542 
    543     // Allow the temporary parameters to be garbage-collected
    544     JS_RemoveRoot(g_ScriptingHost.getContext(), &mouseObj);
    545     JS_RemoveRoot(g_ScriptingHost.getContext(), &jsGuiObject);
    546532}
    547533
    548534void IGUIObject::ScriptEvent(const CStr& Action, const CScriptValRooted& Argument)
     
    571557    if (! m_JSObject)
    572558    {
    573559        m_JSObject = JS_NewObject(g_ScriptingHost.getContext(), &JSI_IGUIObject::JSI_class, NULL, NULL);
    574         JS_AddRoot(g_ScriptingHost.getContext(), &m_JSObject);
     560        JS_AddObjectRoot(g_ScriptingHost.getContext(), &m_JSObject);
    575561        JS_SetPrivate(g_ScriptingHost.getContext(), m_JSObject, this);
    576562    }
    577563    return m_JSObject;
  • source/gui/IGUIObject.h

    diff -r 6b3ac7e864ba source/gui/IGUIObject.h
    a b  
    145145    friend class GUITooltip;
    146146
    147147    // Allow getProperty to access things like GetParent()
    148     friend JSBool JSI_IGUIObject::getProperty(JSContext* cx, JSObject* obj, jsval id, jsval* vp);
    149     friend JSBool JSI_IGUIObject::setProperty(JSContext* cx, JSObject* obj, jsval id, jsval* vp);
     148    friend JSBool JSI_IGUIObject::getProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp);
     149    friend JSBool JSI_IGUIObject::setProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp);
    150150
    151151public:
    152152    IGUIObject();
  • source/gui/scripting/JSInterface_GUITypes.cpp

    diff -r 6b3ac7e864ba source/gui/scripting/JSInterface_GUITypes.cpp
    a b  
    4545
    4646JSFunctionSpec JSI_GUISize::JSI_methods[] =
    4747{
    48     { "toString", JSI_GUISize::toString, 0, 0, 0 },
     48    { "toString", JSI_GUISize::toString, 0, 0 },
    4949    { 0 }
    5050};
    5151
    52 JSBool JSI_GUISize::construct(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* UNUSED(rval))
     52JSBool JSI_GUISize::construct(JSContext* cx, uintN argc, jsval* vp)
    5353{
     54    JSObject* obj = JS_NewObject(cx, &JSI_GUISize::JSI_class, NULL, NULL);
     55
    5456    if (argc == 8)
    5557    {
    56         JS_SetProperty(cx, obj, "left",     &argv[0]);
    57         JS_SetProperty(cx, obj, "top",      &argv[1]);
    58         JS_SetProperty(cx, obj, "right",    &argv[2]);
    59         JS_SetProperty(cx, obj, "bottom",   &argv[3]);
    60         JS_SetProperty(cx, obj, "rleft",    &argv[4]);
    61         JS_SetProperty(cx, obj, "rtop",     &argv[5]);
    62         JS_SetProperty(cx, obj, "rright",   &argv[6]);
    63         JS_SetProperty(cx, obj, "rbottom",  &argv[7]);
     58        JS_SetProperty(cx, obj, "left",     &JS_ARGV(cx, vp)[0]);
     59        JS_SetProperty(cx, obj, "top",      &JS_ARGV(cx, vp)[1]);
     60        JS_SetProperty(cx, obj, "right",    &JS_ARGV(cx, vp)[2]);
     61        JS_SetProperty(cx, obj, "bottom",   &JS_ARGV(cx, vp)[3]);
     62        JS_SetProperty(cx, obj, "rleft",    &JS_ARGV(cx, vp)[4]);
     63        JS_SetProperty(cx, obj, "rtop",     &JS_ARGV(cx, vp)[5]);
     64        JS_SetProperty(cx, obj, "rright",   &JS_ARGV(cx, vp)[6]);
     65        JS_SetProperty(cx, obj, "rbottom",  &JS_ARGV(cx, vp)[7]);
    6466    }
    6567    else if (argc == 4)
    6668    {
    6769        jsval zero = JSVAL_ZERO;
    68         JS_SetProperty(cx, obj, "left",     &argv[0]);
    69         JS_SetProperty(cx, obj, "top",      &argv[1]);
    70         JS_SetProperty(cx, obj, "right",    &argv[2]);
    71         JS_SetProperty(cx, obj, "bottom",   &argv[3]);
     70        JS_SetProperty(cx, obj, "left",     &JS_ARGV(cx, vp)[0]);
     71        JS_SetProperty(cx, obj, "top",      &JS_ARGV(cx, vp)[1]);
     72        JS_SetProperty(cx, obj, "right",    &JS_ARGV(cx, vp)[2]);
     73        JS_SetProperty(cx, obj, "bottom",   &JS_ARGV(cx, vp)[3]);
    7274        JS_SetProperty(cx, obj, "rleft",    &zero);
    7375        JS_SetProperty(cx, obj, "rtop",     &zero);
    7476        JS_SetProperty(cx, obj, "rright",   &zero);
     
    8789        JS_SetProperty(cx, obj, "rbottom",  &zero);
    8890    }
    8991
     92    JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
    9093    return JS_TRUE;
    9194}
    9295
     
    99102        return CStr(per)+CStr("%")+( pix == 0.0 ? CStr() : pix > 0.0 ? CStr("+")+CStr(pix) : CStr(pix) );
    100103}
    101104
    102 JSBool JSI_GUISize::toString(JSContext* cx, JSObject* obj, uintN UNUSED(argc), jsval* UNUSED(argv), jsval* rval)
     105JSBool JSI_GUISize::toString(JSContext* cx, uintN argc, jsval* vp)
    103106{
     107    UNUSED2(argc);
     108
    104109    CStr buffer;
    105110
    106111    try
    107112    {
    108 #define SIDE(side) buffer += ToPercentString(g_ScriptingHost.GetObjectProperty_Double(obj, #side), g_ScriptingHost.GetObjectProperty_Double(obj, "r"#side));
     113#define SIDE(side) buffer += ToPercentString(g_ScriptingHost.GetObjectProperty_Double(JS_THIS_OBJECT(cx, vp), #side), g_ScriptingHost.GetObjectProperty_Double(JS_THIS_OBJECT(cx, vp), "r"#side));
    109114        SIDE(left);
    110115        buffer += " ";
    111116        SIDE(top);
     
    117122    }
    118123    catch (PSERROR_Scripting_ConversionFailed)
    119124    {
    120         *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, "<Error converting value to numbers>"));
     125        JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, "<Error converting value to numbers>")));
    121126        return JS_TRUE;
    122127    }
    123128
    124     *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buffer.c_str()));
     129    JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buffer.c_str())));
    125130    return JS_TRUE;
    126131}
    127132
     
    149154
    150155JSFunctionSpec JSI_GUIColor::JSI_methods[] =
    151156{
    152     { "toString", JSI_GUIColor::toString, 0, 0, 0 },
     157    { "toString", JSI_GUIColor::toString, 0, 0 },
    153158    { 0 }
    154159};
    155160
    156 JSBool JSI_GUIColor::construct(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* UNUSED(rval))
     161JSBool JSI_GUIColor::construct(JSContext* cx, uintN argc, jsval* vp)
    157162{
     163    JSObject* obj = JS_NewObject(cx, &JSI_GUIColor::JSI_class, NULL, NULL);
     164
    158165    if (argc == 4)
    159166    {
    160         JS_SetProperty(cx, obj, "r", &argv[0]);
    161         JS_SetProperty(cx, obj, "g", &argv[1]);
    162         JS_SetProperty(cx, obj, "b", &argv[2]);
    163         JS_SetProperty(cx, obj, "a", &argv[3]);
     167        JS_SetProperty(cx, obj, "r", &JS_ARGV(cx, vp)[0]);
     168        JS_SetProperty(cx, obj, "g", &JS_ARGV(cx, vp)[1]);
     169        JS_SetProperty(cx, obj, "b", &JS_ARGV(cx, vp)[2]);
     170        JS_SetProperty(cx, obj, "a", &JS_ARGV(cx, vp)[3]);
    164171    }
    165172    else
    166173    {
    167174        // Nice magenta:
    168         jsval r = DOUBLE_TO_JSVAL(JS_NewDouble(cx, 1.0));
    169         JS_SetProperty(cx, obj, "r", &r);
    170         jsval g = DOUBLE_TO_JSVAL(JS_NewDouble(cx, 0.0));
    171         JS_SetProperty(cx, obj, "g", &g);
    172         jsval b = DOUBLE_TO_JSVAL(JS_NewDouble(cx, 1.0));
    173         JS_SetProperty(cx, obj, "b", &b);
    174         jsval a = DOUBLE_TO_JSVAL(JS_NewDouble(cx, 1.0));
    175         JS_SetProperty(cx, obj, "a", &a);
     175        jsval c;
     176        if (!JS_NewNumberValue(cx, 1.0, &c))
     177            return JS_FALSE;
     178        JS_SetProperty(cx, obj, "r", &c);
     179        JS_SetProperty(cx, obj, "b", &c);
     180        JS_SetProperty(cx, obj, "a", &c);
     181        if (!JS_NewNumberValue(cx, 0.0, &c))
     182            return JS_FALSE;
     183        JS_SetProperty(cx, obj, "g", &c);
    176184    }
     185
     186    JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
    177187    return JS_TRUE;
    178188}
    179189
    180 JSBool JSI_GUIColor::toString(JSContext* cx, JSObject* obj,
    181     uintN UNUSED(argc), jsval* UNUSED(argv), jsval* rval)
     190JSBool JSI_GUIColor::toString(JSContext* cx, uintN argc, jsval* vp)
    182191{
     192    UNUSED2(argc);
     193
     194    jsdouble r, g, b, a;
     195    if (!JS_ValueToNumber(cx, g_ScriptingHost.GetObjectProperty(JS_THIS_OBJECT(cx, vp), "r"), &r)) return JS_FALSE;
     196    if (!JS_ValueToNumber(cx, g_ScriptingHost.GetObjectProperty(JS_THIS_OBJECT(cx, vp), "g"), &g)) return JS_FALSE;
     197    if (!JS_ValueToNumber(cx, g_ScriptingHost.GetObjectProperty(JS_THIS_OBJECT(cx, vp), "b"), &b)) return JS_FALSE;
     198    if (!JS_ValueToNumber(cx, g_ScriptingHost.GetObjectProperty(JS_THIS_OBJECT(cx, vp), "a"), &a)) return JS_FALSE;
     199
    183200    char buffer[256];
    184201    // Convert to integers, to be compatible with the GUI's string SetSetting
    185202    snprintf(buffer, 256, "%d %d %d %d",
    186         (int)( 255.0 * *JSVAL_TO_DOUBLE(g_ScriptingHost.GetObjectProperty(obj, "r")) ),
    187         (int)( 255.0 * *JSVAL_TO_DOUBLE(g_ScriptingHost.GetObjectProperty(obj, "g")) ),
    188         (int)( 255.0 * *JSVAL_TO_DOUBLE(g_ScriptingHost.GetObjectProperty(obj, "b")) ),
    189         (int)( 255.0 * *JSVAL_TO_DOUBLE(g_ScriptingHost.GetObjectProperty(obj, "a")) ));
    190     *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buffer));
     203        (int)(255.0 * r),
     204        (int)(255.0 * g),
     205        (int)(255.0 * b),
     206        (int)(255.0 * a));
     207    JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buffer)));
    191208    return JS_TRUE;
    192209}
    193210
     
    213230
    214231JSFunctionSpec JSI_GUIMouse::JSI_methods[] =
    215232{
    216     { "toString", JSI_GUIMouse::toString, 0, 0, 0 },
     233    { "toString", JSI_GUIMouse::toString, 0, 0 },
    217234    { 0 }
    218235};
    219236
    220 JSBool JSI_GUIMouse::construct(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* UNUSED(rval))
     237JSBool JSI_GUIMouse::construct(JSContext* cx, uintN argc, jsval* vp)
    221238{
     239    JSObject* obj = JS_NewObject(cx, &JSI_GUIMouse::JSI_class, NULL, NULL);
     240
    222241    if (argc == 3)
    223242    {
    224         JS_SetProperty(cx, obj, "x", &argv[0]);
    225         JS_SetProperty(cx, obj, "y", &argv[1]);
    226         JS_SetProperty(cx, obj, "buttons", &argv[2]);
     243        JS_SetProperty(cx, obj, "x", &JS_ARGV(cx, vp)[0]);
     244        JS_SetProperty(cx, obj, "y", &JS_ARGV(cx, vp)[1]);
     245        JS_SetProperty(cx, obj, "buttons", &JS_ARGV(cx, vp)[2]);
    227246    }
    228247    else
    229248    {
     
    232251        JS_SetProperty(cx, obj, "y", &zero);
    233252        JS_SetProperty(cx, obj, "buttons", &zero);
    234253    }
     254
     255    JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
    235256    return JS_TRUE;
    236257}
    237258
    238 JSBool JSI_GUIMouse::toString(JSContext* cx, JSObject* obj, uintN UNUSED(argc), jsval* UNUSED(argv), jsval* rval)
     259JSBool JSI_GUIMouse::toString(JSContext* cx, uintN argc, jsval* vp)
    239260{
     261    UNUSED2(argc);
     262
     263    int32 x, y, buttons;
     264    if (!JS_ValueToECMAInt32(cx, g_ScriptingHost.GetObjectProperty(JS_THIS_OBJECT(cx, vp), "x"), &x)) return JS_FALSE;
     265    if (!JS_ValueToECMAInt32(cx, g_ScriptingHost.GetObjectProperty(JS_THIS_OBJECT(cx, vp), "y"), &y)) return JS_FALSE;
     266    if (!JS_ValueToECMAInt32(cx, g_ScriptingHost.GetObjectProperty(JS_THIS_OBJECT(cx, vp), "buttons"), &buttons)) return JS_FALSE;
     267
    240268    char buffer[256];
    241     snprintf(buffer, 256, "%d %d %d",
    242         JSVAL_TO_INT(g_ScriptingHost.GetObjectProperty(obj, "x")),
    243         JSVAL_TO_INT(g_ScriptingHost.GetObjectProperty(obj, "y")),
    244         JSVAL_TO_INT(g_ScriptingHost.GetObjectProperty(obj, "buttons")) );
    245     *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buffer));
     269    snprintf(buffer, 256, "%d %d %d", x, y, buttons);
     270    JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buffer)));
    246271    return JS_TRUE;
    247272}
    248273
  • source/gui/scripting/JSInterface_GUITypes.h

    diff -r 6b3ac7e864ba source/gui/scripting/JSInterface_GUITypes.h
    a b  
    2626        extern JSClass JSI_class;               \
    2727        extern JSPropertySpec JSI_props[];      \
    2828        extern JSFunctionSpec JSI_methods[];    \
    29         JSBool construct( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval ); \
    30         JSBool toString( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );  \
     29        JSBool construct(JSContext* cx, uintN argc, jsval* vp); \
     30        JSBool toString(JSContext* cx, uintN argc, jsval* vp);  \
    3131    }
    3232
    3333GUISTDTYPE(Size)
  • source/gui/scripting/JSInterface_IGUIObject.cpp

    diff -r 6b3ac7e864ba source/gui/scripting/JSInterface_IGUIObject.cpp
    a b  
    4646
    4747JSFunctionSpec JSI_IGUIObject::JSI_methods[] =
    4848{
    49     { "toString", JSI_IGUIObject::toString, 0, 0, 0 },
    50     { "focus", JSI_IGUIObject::focus, 0, 0, 0 },
    51     { "blur", JSI_IGUIObject::blur, 0, 0, 0 },
     49    { "toString", JSI_IGUIObject::toString, 0, 0 },
     50    { "focus", JSI_IGUIObject::focus, 0, 0 },
     51    { "blur", JSI_IGUIObject::blur, 0, 0 },
    5252    { 0 }
    5353};
    5454
    55 JSBool JSI_IGUIObject::getProperty(JSContext* cx, JSObject* obj, jsval id, jsval* vp)
     55JSBool JSI_IGUIObject::getProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp)
    5656{
    57     CStr propName = JS_GetStringBytes(JS_ValueToString(cx, id));
     57    IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, obj, &JSI_IGUIObject::JSI_class, NULL);
     58    if (!e)
     59        return JS_FALSE;
     60
     61    jsval idval;
     62    if (!JS_IdToValue(cx, id, &idval))
     63        return JS_FALSE;
     64
     65    CStr propName = g_ScriptingHost.ValueToString(idval);
    5866
    5967    // Skip some things which are known to be functions rather than properties.
    6068    // ("constructor" *must* be here, else it'll try to GetSettingType before
     
    6977       )
    7078        return JS_TRUE;
    7179
    72     IGUIObject* e = (IGUIObject*)JS_GetPrivate(cx, obj);
    73 
    7480    // Use onWhatever to access event handlers
    7581    if (propName.Left(2) == "on")
    7682    {
     
    143149                float value;
    144150                GUI<float>::GetSetting(e, propName, value);
    145151                // Create a garbage-collectable double
    146                 *vp = DOUBLE_TO_JSVAL(JS_NewDouble(cx, value) );
    147                 break;
     152                return JS_NewNumberValue(cx, value, vp);
    148153            }
    149154
    150155        case GUIST_CColor:
     
    154159                JSObject* obj = JS_NewObject(cx, &JSI_GUIColor::JSI_class, NULL, NULL);
    155160                *vp = OBJECT_TO_JSVAL(obj); // root it
    156161
     162                jsval c;
    157163                // Attempt to minimise ugliness through macrosity
    158                 #define P(x) jsval x = DOUBLE_TO_JSVAL(JS_NewDouble(cx, colour.x)); JS_SetProperty(cx, obj, #x, &x)
     164                #define P(x) if (!JS_NewNumberValue(cx, colour.x, &c)) return JS_FALSE; JS_SetProperty(cx, obj, #x, &c)
    159165                    P(r);
    160166                    P(g);
    161167                    P(b);
     
    286292    }
    287293}
    288294
    289 JSBool JSI_IGUIObject::setProperty(JSContext* cx, JSObject* obj, jsval id, jsval* vp)
     295JSBool JSI_IGUIObject::setProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp)
    290296{
    291     IGUIObject* e = (IGUIObject*)JS_GetPrivate(cx, obj);
    292     CStr propName = g_ScriptingHost.ValueToString(id);
     297    IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, obj, &JSI_IGUIObject::JSI_class, NULL);
     298    if (!e)
     299        return JS_FALSE;
     300
     301    jsval idval;
     302    if (!JS_IdToValue(cx, id, &idval))
     303        return JS_FALSE;
     304
     305    CStr propName = g_ScriptingHost.ValueToString(idval);
     306
    293307    if (propName == "name")
    294308    {
    295309        CStr propValue = JS_GetStringBytes(JS_ValueToString(cx, *vp));
     
    549563}
    550564
    551565
    552 JSBool JSI_IGUIObject::construct(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* UNUSED(rval))
     566JSBool JSI_IGUIObject::construct(JSContext* cx, uintN argc, jsval* vp)
    553567{
    554568    if (argc == 0)
    555569    {
     
    557571        return JS_FALSE;
    558572    }
    559573
    560     debug_assert(argc == 1);
     574    JSObject* obj = JS_NewObject(cx, &JSI_IGUIObject::JSI_class, NULL, NULL);
    561575
    562576    // Store the IGUIObject in the JS object's 'private' area
    563     IGUIObject* guiObject = (IGUIObject*)JSVAL_TO_PRIVATE(argv[0]);
     577    IGUIObject* guiObject = (IGUIObject*)JSVAL_TO_PRIVATE(JS_ARGV(cx, vp)[0]);
    564578    JS_SetPrivate(cx, obj, guiObject);
    565579
     580    JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
    566581    return JS_TRUE;
    567582}
    568583
     
    571586    g_ScriptingHost.DefineCustomObjectType(&JSI_class, construct, 1, JSI_props, JSI_methods, NULL, NULL);
    572587}
    573588
    574 JSBool JSI_IGUIObject::toString(JSContext* cx, JSObject* obj, uintN UNUSED(argc), jsval* UNUSED(argv), jsval* rval)
     589JSBool JSI_IGUIObject::toString(JSContext* cx, uintN argc, jsval* vp)
    575590{
    576     IGUIObject* e = (IGUIObject*)JS_GetPrivate( cx, obj );
     591    UNUSED2(argc);
     592
     593    IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, JS_THIS_OBJECT(cx, vp), &JSI_IGUIObject::JSI_class, NULL);
     594    if (!e)
     595        return JS_FALSE;
    577596
    578597    char buffer[256];
    579598    snprintf(buffer, 256, "[GUIObject: %s]", e->GetName().c_str());
    580599    buffer[255] = 0;
    581     *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buffer));
     600    JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buffer)));
    582601    return JS_TRUE;
    583602}
    584603
    585 JSBool JSI_IGUIObject::focus(JSContext* cx, JSObject* obj, uintN UNUSED(argc), jsval* UNUSED(argv), jsval* UNUSED(rval))
     604JSBool JSI_IGUIObject::focus(JSContext* cx, uintN argc, jsval* vp)
    586605{
    587     IGUIObject* e = (IGUIObject*)JS_GetPrivate( cx, obj );
     606    UNUSED2(argc);
     607
     608    IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, JS_THIS_OBJECT(cx, vp), &JSI_IGUIObject::JSI_class, NULL);
     609    if (!e)
     610        return JS_FALSE;
    588611
    589612    e->GetGUI()->SetFocusedObject(e);
    590613    return JS_TRUE;
    591614}
    592615
    593 JSBool JSI_IGUIObject::blur(JSContext* cx, JSObject* obj, uintN UNUSED(argc), jsval* UNUSED(argv), jsval* UNUSED(rval))
     616JSBool JSI_IGUIObject::blur(JSContext* cx, uintN argc, jsval* vp)
    594617{
    595     IGUIObject* e = (IGUIObject*)JS_GetPrivate( cx, obj );
     618    UNUSED2(argc);
     619
     620    IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, JS_THIS_OBJECT(cx, vp), &JSI_IGUIObject::JSI_class, NULL);
     621    if (!e)
     622        return JS_FALSE;
    596623
    597624    e->GetGUI()->SetFocusedObject(NULL);
    598625    return JS_TRUE;
  • source/gui/scripting/JSInterface_IGUIObject.h

    diff -r 6b3ac7e864ba source/gui/scripting/JSInterface_IGUIObject.h
    a b  
    2525    extern JSClass JSI_class;
    2626    extern JSPropertySpec JSI_props[];
    2727    extern JSFunctionSpec JSI_methods[];
    28     JSBool addProperty(JSContext* cx, JSObject* obj, jsval id, jsval* vp);
    29     JSBool delProperty(JSContext* cx, JSObject* obj, jsval id, jsval* vp);
    30     JSBool getProperty(JSContext* cx, JSObject* obj, jsval id, jsval* vp);
    31     JSBool setProperty(JSContext* cx, JSObject* obj, jsval id, jsval* vp);
    32     JSBool construct(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval);
    33     JSBool toString(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval);
    34     JSBool focus(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval);
    35     JSBool blur(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval);
     28    JSBool getProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp);
     29    JSBool setProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp);
     30    JSBool construct(JSContext* cx, uintN argc, jsval* vp);
     31    JSBool toString(JSContext* cx, uintN argc, jsval* vp);
     32    JSBool focus(JSContext* cx, uintN argc, jsval* vp);
     33    JSBool blur(JSContext* cx, uintN argc, jsval* vp);
    3634    void init();
    3735}
    3836
  • source/maths/scripting/JSInterface_Vector3D.cpp

    diff -r 6b3ac7e864ba source/maths/scripting/JSInterface_Vector3D.cpp
    a b  
    2121#include "scripting/JSConversions.h"
    2222#include "scripting/ScriptingHost.h"
    2323
    24 namespace JSI_Vector3D
    25 {
    26     static CVector3D* GetVector( JSContext* cx, JSObject* obj );
    27 }
    28 
    2924JSClass JSI_Vector3D::JSI_class = {
    3025    "Vector3D", JSCLASS_HAS_PRIVATE,
    3126    JS_PropertyStub, JS_PropertyStub,
     
    4540
    4641JSFunctionSpec JSI_Vector3D::JSI_methods[] =
    4742{
    48     { "toString", JSI_Vector3D::toString, 0, 0, 0 },
    49     { "add", JSI_Vector3D::add, 1, 0, 0 },
    50     { "subtract", JSI_Vector3D::subtract, 1, 0, 0 },
    51     { "minus", JSI_Vector3D::subtract, 1, 0, 0 },
    52     { "negate", JSI_Vector3D::negate, 1, 0, 0 },
    53     { "scale", JSI_Vector3D::scale, 1, 0, 0 },
    54     { "multiply", JSI_Vector3D::scale, 1, 0, 0 },
    55     { "divide", JSI_Vector3D::divide, 1, 0, 0 },
    56     { "dot", JSI_Vector3D::dot, 1, 0, 0 },
    57     { "cross", JSI_Vector3D::cross, 1, 0, 0 },
    58     { "length", JSI_Vector3D::length, 0, 0, 0 },
    59     { "normalize", JSI_Vector3D::normalize, 0, 0, 0 },
     43    { "toString", JSI_Vector3D::toString, 0, 0 },
    6044    { 0 }
    6145};
    6246
    6347void JSI_Vector3D::init()
    6448{
    65     g_ScriptingHost.DefineCustomObjectType( &JSI_class, JSI_Vector3D::construct, 0, JSI_props, JSI_methods, NULL, NULL );
     49    g_ScriptingHost.DefineCustomObjectType(&JSI_class, JSI_Vector3D::construct, 0, JSI_props, JSI_methods, NULL, NULL);
    6650}
    6751
    6852JSI_Vector3D::Vector3D_Info::Vector3D_Info()
     
    7155    vector = new CVector3D();
    7256}
    7357
    74 JSI_Vector3D::Vector3D_Info::Vector3D_Info( float x, float y, float z )
     58JSI_Vector3D::Vector3D_Info::Vector3D_Info(float x, float y, float z)
    7559{
    7660    owner = NULL;
    77     vector = new CVector3D( x, y, z );
     61    vector = new CVector3D(x, y, z);
    7862}
    7963
    80 JSI_Vector3D::Vector3D_Info::Vector3D_Info( const CVector3D& copy )
     64JSI_Vector3D::Vector3D_Info::Vector3D_Info(const CVector3D& copy)
    8165{
    8266    owner = NULL;
    83     vector = new CVector3D( copy.X, copy.Y, copy.Z );
     67    vector = new CVector3D(copy.X, copy.Y, copy.Z);
    8468}
    8569
    86 JSI_Vector3D::Vector3D_Info::Vector3D_Info( CVector3D* attach, IPropertyOwner* _owner )
     70JSI_Vector3D::Vector3D_Info::Vector3D_Info(CVector3D* attach, IPropertyOwner* _owner)
    8771{
    8872    owner = _owner;
    8973    updateFn = NULL;
     
    9175    vector = attach;
    9276}
    9377
    94 JSI_Vector3D::Vector3D_Info::Vector3D_Info( CVector3D* attach, IPropertyOwner* _owner, void( IPropertyOwner::*_updateFn )(void) )
     78JSI_Vector3D::Vector3D_Info::Vector3D_Info(CVector3D* attach, IPropertyOwner* _owner, void(IPropertyOwner::*_updateFn)(void))
    9579{
    9680    owner = _owner;
    9781    updateFn = _updateFn;
     
    9983    vector = attach;
    10084}
    10185
    102 JSI_Vector3D::Vector3D_Info::Vector3D_Info( CVector3D* attach, IPropertyOwner* _owner, void( IPropertyOwner::*_updateFn )(void), void( IPropertyOwner::*_freshenFn )(void) )
     86JSI_Vector3D::Vector3D_Info::Vector3D_Info(CVector3D* attach, IPropertyOwner* _owner, void(IPropertyOwner::*_updateFn)(void),
     87        void(IPropertyOwner::*_freshenFn)(void))
    10388{
    10489    owner = _owner;
    10590    updateFn = _updateFn;
     
    10994
    11095JSI_Vector3D::Vector3D_Info::~Vector3D_Info()
    11196{
    112     if( !owner ) delete( vector );
     97    if (!owner)
     98        delete (vector);
    11399}
    114100
    115 JSBool JSI_Vector3D::getProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp )
     101JSBool JSI_Vector3D::getProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp)
    116102{
    117     if( !JSVAL_IS_INT( id ) )
    118         return( JS_TRUE );
     103    if (!JSID_IS_INT(id))
     104        return JS_TRUE;
    119105
    120     Vector3D_Info* vectorInfo = (Vector3D_Info*)JS_GetPrivate( cx, obj );
    121     if( !vectorInfo )
     106    Vector3D_Info* vectorInfo = (Vector3D_Info*)JS_GetInstancePrivate(cx, obj, &JSI_Vector3D::JSI_class, NULL);
     107    if (!vectorInfo)
     108        return JS_FALSE;
     109
     110    CVector3D* vectorData = vectorInfo->vector;
     111
     112    if (vectorInfo->owner && vectorInfo->freshenFn)
     113        ((vectorInfo->owner)->*(vectorInfo->freshenFn))();
     114
     115    switch (JSID_TO_INT(id))
    122116    {
    123         JS_ReportError( cx, "[Vector3D] Invalid reference" );
    124         return( JS_TRUE );
     117    case component_x:
     118        return JS_NewNumberValue(cx, vectorData->X, vp);
     119    case component_y:
     120        return JS_NewNumberValue(cx, vectorData->Y, vp);
     121    case component_z:
     122        return JS_NewNumberValue(cx, vectorData->Z, vp);
    125123    }
    126124
    127     CVector3D* vectorData = vectorInfo->vector;
     125    return JS_FALSE;
     126}
    128127
    129     if( vectorInfo->owner && vectorInfo->freshenFn ) ( (vectorInfo->owner)->*(vectorInfo->freshenFn) )();
    130    
    131     switch( ToPrimitive<int>( id ) )
     128JSBool JSI_Vector3D::setProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp)
     129{
     130    if (!JSID_IS_INT(id))
     131        return JS_TRUE;
     132
     133    Vector3D_Info* vectorInfo = (Vector3D_Info*)JS_GetInstancePrivate(cx, obj, &JSI_Vector3D::JSI_class, NULL);
     134    if (!vectorInfo)
     135        return JS_FALSE;
     136
     137    CVector3D* vectorData = vectorInfo->vector;
     138
     139    if (vectorInfo->owner && vectorInfo->freshenFn)
     140        ((vectorInfo->owner)->*(vectorInfo->freshenFn))();
     141
     142    switch (JSID_TO_INT(id))
    132143    {
    133     case component_x: *vp = DOUBLE_TO_JSVAL( JS_NewDouble( cx, vectorData->X ) ); return( JS_TRUE );
    134     case component_y: *vp = DOUBLE_TO_JSVAL( JS_NewDouble( cx, vectorData->Y ) ); return( JS_TRUE );
    135     case component_z: *vp = DOUBLE_TO_JSVAL( JS_NewDouble( cx, vectorData->Z ) ); return( JS_TRUE );
     144    case component_x:
     145        vectorData->X = ToPrimitive<float> (*vp);
     146        break;
     147    case component_y:
     148        vectorData->Y = ToPrimitive<float> (*vp);
     149        break;
     150    case component_z:
     151        vectorData->Z = ToPrimitive<float> (*vp);
     152        break;
    136153    }
    137154
    138     return( JS_FALSE );
     155    if (vectorInfo->owner && vectorInfo->updateFn)
     156        ((vectorInfo->owner)->*(vectorInfo->updateFn))();
     157
     158    return JS_TRUE;
    139159}
    140160
    141 JSBool JSI_Vector3D::setProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp )
     161JSBool JSI_Vector3D::construct(JSContext* cx, uintN argc, jsval* vp)
    142162{
    143     if( !JSVAL_IS_INT( id ) )
    144         return( JS_TRUE );
     163    JSObject* vector = JS_NewObject(cx, &JSI_Vector3D::JSI_class, NULL, NULL);
    145164
    146     Vector3D_Info* vectorInfo = (Vector3D_Info*)JS_GetPrivate( cx, obj );
    147     if( !vectorInfo )
     165    if (argc == 0)
    148166    {
    149         JS_ReportError( cx, "[Vector3D] Invalid reference" );
    150         return( JS_TRUE );
    151     }
    152     CVector3D* vectorData = vectorInfo->vector;
    153 
    154     if( vectorInfo->owner && vectorInfo->freshenFn ) ( (vectorInfo->owner)->*(vectorInfo->freshenFn) )();
    155 
    156     switch( ToPrimitive<int>( id ) )
    157     {
    158     case component_x: vectorData->X = ToPrimitive<float>( *vp ); break;
    159     case component_y: vectorData->Y = ToPrimitive<float>( *vp ); break;
    160     case component_z: vectorData->Z = ToPrimitive<float>( *vp ); break;
    161     }
    162 
    163    
    164     if( vectorInfo->owner && vectorInfo->updateFn ) ( (vectorInfo->owner)->*(vectorInfo->updateFn) )();
    165 
    166     return( JS_TRUE );
    167 }
    168 
    169 JSBool JSI_Vector3D::construct( JSContext* cx, JSObject* UNUSED(obj), uintN argc, jsval* argv, jsval* rval )
    170 {
    171     JSObject* vector = JS_NewObject( cx, &JSI_Vector3D::JSI_class, NULL, NULL );
    172    
    173     if( argc == 0 )
    174     {
    175         JS_SetPrivate( cx, vector, new Vector3D_Info() );
    176         *rval = OBJECT_TO_JSVAL( vector );
    177         return( JS_TRUE );
     167        JS_SetPrivate(cx, vector, new Vector3D_Info());
     168        JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(vector));
     169        return JS_TRUE;
    178170    }
    179171
    180172    JSU_REQUIRE_PARAMS(3);
    181173    try
    182174    {
    183         float x = ToPrimitive<float>( argv[0] );
    184         float y = ToPrimitive<float>( argv[1] );
    185         float z = ToPrimitive<float>( argv[2] );
    186         JS_SetPrivate( cx, vector, new Vector3D_Info( x, y, z ) );
    187         *rval = OBJECT_TO_JSVAL( vector );
    188         return( JS_TRUE );
     175        float x = ToPrimitive<float> (JS_ARGV(cx, vp)[0]);
     176        float y = ToPrimitive<float> (JS_ARGV(cx, vp)[1]);
     177        float z = ToPrimitive<float> (JS_ARGV(cx, vp)[2]);
     178        JS_SetPrivate(cx, vector, new Vector3D_Info(x, y, z));
     179        JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(vector));
     180        return JS_TRUE;
    189181    }
    190182    catch (PSERROR_Scripting_ConversionFailed)
    191183    {
    192184        // Invalid input (i.e. can't be coerced into doubles) - fail
    193         JS_ReportError( cx, "Invalid parameters to Vector3D constructor" );
    194         *rval = JSVAL_NULL;
    195         return( JS_FALSE );
     185        JS_ReportError(cx, "Invalid parameters to Vector3D constructor");
     186        return JS_FALSE;
    196187    }
    197188}
    198189
    199 void JSI_Vector3D::finalize( JSContext* cx, JSObject* obj )
     190void JSI_Vector3D::finalize(JSContext* cx, JSObject* obj)
    200191{
    201     delete( (Vector3D_Info*)JS_GetPrivate( cx, obj ) );
     192    delete ((Vector3D_Info*)JS_GetPrivate(cx, obj));
    202193}
    203194
    204 JSBool JSI_Vector3D::toString( JSContext* cx, JSObject* obj,
    205     uintN UNUSED(argc), jsval* UNUSED(argv), jsval* rval )
     195JSBool JSI_Vector3D::toString(JSContext* cx, uintN argc, jsval* vp)
    206196{
    207197    char buffer[256];
    208     Vector3D_Info* vectorInfo = (Vector3D_Info*)JS_GetPrivate( cx, obj );
     198    Vector3D_Info* vectorInfo = (Vector3D_Info*)JS_GetInstancePrivate(cx, JS_THIS_OBJECT(cx, vp), &JSI_Vector3D::JSI_class, NULL);
     199    if (!vectorInfo)
     200        return JS_FALSE;
    209201
    210     if( !vectorInfo ) return( JS_TRUE );
     202    if (vectorInfo->owner && vectorInfo->freshenFn)
     203        ((vectorInfo->owner)->*(vectorInfo->freshenFn))();
    211204
    212     if( vectorInfo->owner && vectorInfo->freshenFn ) ( (vectorInfo->owner)->*(vectorInfo->freshenFn) )();
    213 
    214     CVector3D* vectorData = vectorInfo->vector;
    215     sprintf_s( buffer, ARRAY_SIZE(buffer), "[object Vector3D: ( %f, %f, %f )]", vectorData->X, vectorData->Y, vectorData->Z );
    216     *rval = STRING_TO_JSVAL( JS_NewStringCopyZ( cx, buffer ) );
    217     return( JS_TRUE );
     205    CVector3D* vectorData = vectorInfo->vector;
     206    sprintf_s(buffer, ARRAY_SIZE(buffer), "[object Vector3D: ( %f, %f, %f )]", vectorData->X, vectorData->Y, vectorData->Z);
     207    JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buffer)));
     208    return JS_TRUE;
    218209}
    219 
    220 CVector3D* JSI_Vector3D::GetVector( JSContext* cx, JSObject* obj )
    221 {
    222     Vector3D_Info* vectorInfo = (Vector3D_Info*)JS_GetInstancePrivate( cx, obj, &JSI_class, NULL );
    223     if( !vectorInfo )
    224     {
    225         JS_ReportError( cx, "[Vector3D] Invalid reference" );
    226         return( NULL );
    227     }
    228     if( vectorInfo->owner && vectorInfo->freshenFn ) ( (vectorInfo->owner)->*(vectorInfo->freshenFn) )();
    229     return( vectorInfo->vector );
    230 }
    231 
    232 #define GET_VECTORS\
    233     CVector3D* a = GetVector( cx, obj );\
    234     if(!a)\
    235         return( JS_TRUE );\
    236     if( ( argc == 0 ) || !JSVAL_IS_OBJECT( argv[0] ) )\
    237     {\
    238 invalid_param:\
    239         JS_ReportError( cx, "[Vector3D] Invalid parameter" );\
    240         return( JS_TRUE );\
    241     }\
    242     CVector3D* b = GetVector( cx, JSVAL_TO_OBJECT( argv[0] ) );\
    243     if(!b)\
    244         goto invalid_param;
    245 
    246 #define GET_VECTOR_AND_FLOAT\
    247     CVector3D* v = GetVector( cx, obj );\
    248     if(!v)\
    249         return( JS_TRUE );\
    250     float f;\
    251     if( ( argc == 0 ) || !ToPrimitive( cx, argv[0], f ) )\
    252     {\
    253         JS_ReportError( cx, "Invalid parameter" );\
    254         return( JS_TRUE );\
    255     }
    256 
    257 
    258 JSBool JSI_Vector3D::add( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval )
    259 {
    260     GET_VECTORS;
    261 
    262     JSObject* vector3d = JS_NewObject( g_ScriptingHost.getContext(), &JSI_Vector3D::JSI_class, NULL, NULL );
    263     JS_SetPrivate( g_ScriptingHost.getContext(), vector3d, new JSI_Vector3D::Vector3D_Info( *a + *b ) );
    264     *rval = OBJECT_TO_JSVAL( vector3d );
    265 
    266     return( JS_TRUE );
    267 }
    268 
    269 JSBool JSI_Vector3D::subtract( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval )
    270 {
    271     GET_VECTORS;
    272 
    273     JSObject* vector3d = JS_NewObject( g_ScriptingHost.getContext(), &JSI_Vector3D::JSI_class, NULL, NULL );
    274     JS_SetPrivate( g_ScriptingHost.getContext(), vector3d, new JSI_Vector3D::Vector3D_Info( *a - *b ) );
    275     *rval = OBJECT_TO_JSVAL( vector3d );
    276 
    277     return( JS_TRUE );
    278 }
    279 
    280 JSBool JSI_Vector3D::negate( JSContext* cx, JSObject* obj,
    281     uintN UNUSED(argc), jsval* UNUSED(argv), jsval* rval )
    282 {
    283     CVector3D* v = GetVector( cx, obj );
    284     if(!v)
    285         return( JS_TRUE );
    286 
    287     *rval = ToJSVal( -( *v ) );
    288 
    289     return( JS_TRUE );
    290 }
    291 
    292 JSBool JSI_Vector3D::scale( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval )
    293 {
    294     GET_VECTOR_AND_FLOAT;
    295 
    296     JSObject* vector3d = JS_NewObject( g_ScriptingHost.getContext(), &JSI_Vector3D::JSI_class, NULL, NULL );
    297     JS_SetPrivate( g_ScriptingHost.getContext(), vector3d, new JSI_Vector3D::Vector3D_Info( *v * f ) );
    298     *rval = OBJECT_TO_JSVAL( vector3d );
    299 
    300     return( JS_TRUE );
    301 }
    302 
    303 JSBool JSI_Vector3D::divide( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval )
    304 {
    305     GET_VECTOR_AND_FLOAT;
    306 
    307     JSObject* vector3d = JS_NewObject( g_ScriptingHost.getContext(), &JSI_Vector3D::JSI_class, NULL, NULL );
    308     JS_SetPrivate( g_ScriptingHost.getContext(), vector3d, new JSI_Vector3D::Vector3D_Info( *v * ( 1.0f / f ) ) );
    309     *rval = OBJECT_TO_JSVAL( vector3d );
    310 
    311     return( JS_TRUE );
    312 }
    313 
    314 JSBool JSI_Vector3D::dot( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval )
    315 {
    316     GET_VECTORS;
    317 
    318     *rval = ToJSVal( a->Dot( *b ) );
    319     return( JS_TRUE );
    320 }
    321 
    322 JSBool JSI_Vector3D::cross( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval )
    323 {
    324     GET_VECTORS;
    325 
    326     *rval = ToJSVal( a->Cross( *b ) );
    327     return( JS_TRUE );
    328 }
    329 
    330 JSBool JSI_Vector3D::length( JSContext* cx, JSObject* obj,
    331     uintN UNUSED(argc), jsval* UNUSED(argv), jsval* rval )
    332 {
    333     CVector3D* v = GetVector( cx, obj );
    334     if(!v)
    335         return( JS_TRUE );
    336 
    337     *rval = ToJSVal( v->Length() );
    338     return( JS_TRUE );
    339 }
    340 
    341 JSBool JSI_Vector3D::normalize( JSContext* cx, JSObject* obj,
    342     uintN UNUSED(argc), jsval* UNUSED(argv), jsval* rval )
    343 {
    344     CVector3D* v = GetVector( cx, obj );
    345     if(!v)
    346         return( JS_TRUE );
    347 
    348     CVector3D r( v->X, v->Y, v->Z );
    349     r.Normalize();
    350 
    351     *rval = ToJSVal( r );
    352     return( JS_TRUE );
    353 }
  • source/maths/scripting/JSInterface_Vector3D.h

    diff -r 6b3ac7e864ba source/maths/scripting/JSInterface_Vector3D.h
    a b  
    3636        component_y,
    3737        component_z
    3838    };
    39     JSBool toString( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );
    40     JSBool add( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );
    41     JSBool subtract( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );
    42     JSBool negate( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );
    43     JSBool scale( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );
    44     JSBool divide( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );
    45     JSBool dot( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );
    46     JSBool cross( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );
    47     JSBool length( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );
    48     JSBool normalize( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );
     39    JSBool toString(JSContext* cx, uintN argc, jsval* vp);
    4940
    5041    struct Vector3D_Info
    5142    {
    5243        IPropertyOwner* owner;
    53         void ( IPropertyOwner::*updateFn )();
    54         void ( IPropertyOwner::*freshenFn )();
     44        void (IPropertyOwner::*updateFn)();
     45        void (IPropertyOwner::*freshenFn)();
    5546        CVector3D* vector;
    5647        Vector3D_Info();
    57         Vector3D_Info( float x, float y, float z );
    58         Vector3D_Info( const CVector3D& copy );
    59         Vector3D_Info( CVector3D* attach, IPropertyOwner* _owner );
    60         Vector3D_Info( CVector3D* attach, IPropertyOwner* _owner, void (IPropertyOwner::*_updateFn)(void) );
    61         Vector3D_Info( CVector3D* attach, IPropertyOwner* _owner, void (IPropertyOwner::*_updateFn)(void), void (IPropertyOwner::*_freshenFn)(void) );
     48        Vector3D_Info(float x, float y, float z);
     49        Vector3D_Info(const CVector3D& copy);
     50        Vector3D_Info(CVector3D* attach, IPropertyOwner* _owner);
     51        Vector3D_Info(CVector3D* attach, IPropertyOwner* _owner, void(IPropertyOwner::*_updateFn)(void));
     52        Vector3D_Info(CVector3D* attach, IPropertyOwner* _owner, void(IPropertyOwner::*_updateFn)(void), void(IPropertyOwner::*_freshenFn)(void));
    6253        ~Vector3D_Info();
    6354    };
    6455    extern JSClass JSI_class;
    6556    extern JSPropertySpec JSI_props[];
    6657    extern JSFunctionSpec JSI_methods[];
    6758
    68     JSBool getProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp );
    69     JSBool setProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp );
    70     void finalize( JSContext* cx, JSObject* obj );
    71     JSBool construct( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );
    72     void init();
     59    JSBool getProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp);
     60    JSBool setProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp);
     61    void finalize(JSContext* cx, JSObject* obj);
     62    JSBool construct(JSContext* cx, uintN argc, jsval* vp);
     63    void init();
    7364}
    7465
    7566#endif
    76 
    77 
  • source/ps/ConfigDB.cpp

    diff -r 6b3ac7e864ba source/ps/ConfigDB.cpp
    a b  
    3535
    3636namespace ConfigNamespace_JS
    3737{
    38     JSBool GetProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp )
     38    JSBool GetProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp)
     39{
     40        EConfigNamespace cfgNs = GET_NS_PRIVATE(cx, obj);
     41        if (cfgNs < 0 || cfgNs >= CFG_LAST)
     42            return JS_FALSE;
     43
     44        jsval idval;
     45        if (!JS_IdToValue(cx, id, &idval))
     46            return JS_FALSE;
     47
     48        CStr propName = g_ScriptingHost.ValueToString(idval);
     49        CConfigValue *val = g_ConfigDB.GetValue(cfgNs, propName);
     50        if (val)
     51        {
     52            JSString *js_str = JS_NewStringCopyN(cx, val->m_String.c_str(), val->m_String.size());
     53            *vp = STRING_TO_JSVAL(js_str);
     54        }
     55        return JS_TRUE;
     56    }
     57
     58    JSBool SetProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp)
    3959    {
    4060        EConfigNamespace cfgNs = GET_NS_PRIVATE(cx, obj);
    4161        if (cfgNs < 0 || cfgNs >= CFG_LAST)
    4262            return JS_FALSE;
    4363
    44         CStr propName = g_ScriptingHost.ValueToString(id);
    45         CConfigValue *val=g_ConfigDB.GetValue(cfgNs, propName);
    46         if (val)
    47         {
    48             JSString *js_str=JS_NewStringCopyN(cx, val->m_String.c_str(), val->m_String.size());
    49             *vp = STRING_TO_JSVAL(js_str);
    50         }
    51         return JS_TRUE;
    52     }
    53 
    54     JSBool SetProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp )
    55     {
    56         EConfigNamespace cfgNs = GET_NS_PRIVATE(cx, obj);
    57         if (cfgNs < 0 || cfgNs >= CFG_LAST)
     64        jsval idval;
     65        if (!JS_IdToValue(cx, id, &idval))
    5866            return JS_FALSE;
    5967
    60         CStr propName = g_ScriptingHost.ValueToString(id);
    61         CConfigValue *val=g_ConfigDB.CreateValue(cfgNs, propName);
     68        CStr propName = g_ScriptingHost.ValueToString(idval);
     69        CConfigValue *val = g_ConfigDB.CreateValue(cfgNs, propName);
    6270        char *str;
    6371        if (JS_ConvertArguments(cx, 1, vp, "s", &str))
    6472        {
    65             val->m_String=str;
     73            val->m_String = str;
    6674            return JS_TRUE;
    6775        }
    6876        else
     
    7785        JS_ConvertStub, JS_FinalizeStub
    7886    };
    7987
    80     JSBool Construct( JSContext* cx, JSObject* obj, uintN argc, jsval* UNUSED(argv), jsval* rval )
     88    JSBool Construct(JSContext* cx, uintN argc, jsval* vp)
    8189    {
    82         if (argc != 0)
    83             return JS_FALSE;
     90        UNUSED2(argc);
    8491
    85         JSObject *newObj=JS_NewObject(cx, &Class, NULL, obj);
    86         *rval=OBJECT_TO_JSVAL(newObj);
     92        JSObject *newObj = JS_NewObject(cx, &Class, NULL, NULL);
     93        JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(newObj));
    8794        return JS_TRUE;
    8895    }
    8996
     
    9299        JS_SetPrivate(cx, obj, (void *)((uintptr_t)cfgNs << 1)); // JS requires bottom bit = 0
    93100    }
    94101
    95     JSBool WriteFile( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval )
     102    JSBool WriteFile(JSContext* cx, uintN argc, jsval* vp)
    96103    {
    97         EConfigNamespace cfgNs = GET_NS_PRIVATE(cx, obj);
     104        EConfigNamespace cfgNs = GET_NS_PRIVATE(cx, JS_THIS_OBJECT(cx, vp));
    98105        if (cfgNs < 0 || cfgNs >= CFG_LAST)
    99106            return JS_FALSE;
    100107       
     
    103110
    104111        JSBool useVFS;
    105112        char *path;
    106         if (JS_ConvertArguments(cx, 2, argv, "bs", &useVFS, &path))
     113        if (JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "bs", &useVFS, &path))
    107114        {
    108             JSBool res=g_ConfigDB.WriteFile(cfgNs, useVFS?true:false, CStrW(path));
    109             *rval = BOOLEAN_TO_JSVAL(res);
     115            JSBool res = g_ConfigDB.WriteFile(cfgNs, useVFS ? true : false, CStrW(path));
     116            JS_SET_RVAL(cx, vp, BOOLEAN_TO_JSVAL(res));
    110117            return JS_TRUE;
    111118        }
    112119        else
    113120            return JS_FALSE;
    114121    }
    115122
    116     JSBool Reload( JSContext* cx, JSObject* obj, uintN argc, jsval* UNUSED(argv), jsval* rval )
     123    JSBool Reload(JSContext* cx, uintN argc, jsval* vp)
    117124    {
    118125        if (argc != 0)
    119126            return JS_FALSE;
    120127
    121         EConfigNamespace cfgNs = GET_NS_PRIVATE(cx, obj);
     128        EConfigNamespace cfgNs = GET_NS_PRIVATE(cx, JS_THIS_OBJECT(cx, vp));
    122129        if (cfgNs < 0 || cfgNs >= CFG_LAST)
    123130            return JS_FALSE;
    124131
    125         JSBool ret=g_ConfigDB.Reload(cfgNs);
    126         *rval = BOOLEAN_TO_JSVAL(ret);
     132        JSBool ret = g_ConfigDB.Reload(cfgNs);
     133        JS_SET_RVAL(cx, vp, BOOLEAN_TO_JSVAL(ret));
    127134        return JS_TRUE;
    128135    }
    129136
    130     JSBool SetFile( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* UNUSED(rval) )
     137    JSBool SetFile(JSContext* cx, uintN argc, jsval* vp)
    131138    {
    132139        if (argc != 0)
    133140            return JS_FALSE;
    134141
    135         EConfigNamespace cfgNs = GET_NS_PRIVATE(cx, obj);
     142        EConfigNamespace cfgNs = GET_NS_PRIVATE(cx, JS_THIS_OBJECT(cx, vp));
    136143        if (cfgNs < 0 || cfgNs >= CFG_LAST)
    137144            return JS_FALSE;
    138145
    139146        JSBool useVFS;
    140147        char *path;
    141         if (JS_ConvertArguments(cx, 2, argv, "bs", &useVFS, &path))
     148        if (JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "bs", &useVFS, &path))
    142149        {
    143             g_ConfigDB.SetConfigFile(cfgNs, useVFS?true:false, CStrW(path));
     150            g_ConfigDB.SetConfigFile(cfgNs, useVFS ? true : false, CStrW(path));
     151            JS_SET_RVAL(cx, vp, JSVAL_VOID);
    144152            return JS_TRUE;
    145153        }
    146154        else
     
    148156    }
    149157
    150158    JSFunctionSpec Funcs[] = {
    151         { "writeFile", WriteFile, 2, 0, 0},
    152         { "reload", Reload, 0, 0, 0},
    153         { "setFile", SetFile, 2, 0, 0},
     159        { "writeFile", WriteFile, 2, 0 },
     160        { "reload", Reload, 0, 0 },
     161        { "setFile", SetFile, 2, 0 },
    154162        {0}
    155163    };
    156164};
     
    173181        {0}
    174182    };
    175183
    176     JSBool Construct( JSContext* cx, JSObject* obj, uintN argc, jsval* UNUSED(argv), jsval* rval )
     184    JSBool Construct(JSContext* cx, uintN argc, jsval* vp)
    177185    {
    178         if (argc != 0)
    179             return JS_FALSE;
     186        UNUSED2(argc);
    180187
    181         JSObject *newObj=JS_NewObject(cx, &Class, NULL, obj);
    182         *rval=OBJECT_TO_JSVAL(newObj);
     188        JSObject *newObj = JS_NewObject(cx, &Class, NULL, NULL);
     189        JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(newObj));
    183190
    184191        int flags=JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT;
    185192#define cfg_ns(_propname, _enum) STMT (\
     
    204211{
    205212    g_ScriptingHost.DefineCustomObjectType(&ConfigDB_JS::Class, ConfigDB_JS::Construct, 0, ConfigDB_JS::Props, ConfigDB_JS::Funcs, NULL, NULL);
    206213    g_ScriptingHost.DefineCustomObjectType(&ConfigNamespace_JS::Class, ConfigNamespace_JS::Construct, 0, NULL, ConfigNamespace_JS::Funcs, NULL, NULL);
    207     JSObject *js_ConfigDB=g_ScriptingHost.CreateCustomObject("ConfigDB");
     214    JSObject *js_ConfigDB = g_ScriptingHost.CreateCustomObject("ConfigDB");
    208215    g_ScriptingHost.SetGlobal("g_ConfigDB", OBJECT_TO_JSVAL(js_ConfigDB));
    209216}
    210217
    211218CConfigValue *CConfigDB::GetValue(EConfigNamespace ns, const CStr& name)
    212219{
    213     CConfigValueSet* values = GetValues( ns, name );
    214     if( !values ) return( NULL );
    215     return &( (*values)[0] );
     220    CConfigValueSet* values = GetValues(ns, name);
     221    if (!values)
     222        return (NULL);
     223    return &((*values)[0]);
    216224}
    217225
    218226CConfigValueSet *CConfigDB::GetValues(EConfigNamespace ns, const CStr& name)
     
    223231        return NULL;
    224232    }
    225233
    226     TConfigMap::iterator it = m_Map[CFG_COMMAND].find( name );
    227     if( it != m_Map[CFG_COMMAND].end() )
    228         return &( it->second );
     234    TConfigMap::iterator it = m_Map[CFG_COMMAND].find(name);
     235    if (it != m_Map[CFG_COMMAND].end())
     236        return &(it->second);
    229237
    230     for( int search_ns = ns; search_ns >= 0; search_ns-- )
     238    for (int search_ns = ns; search_ns >= 0; search_ns--)
    231239    {
    232240        TConfigMap::iterator it = m_Map[search_ns].find(name);
    233241        if (it != m_Map[search_ns].end())
    234             return &( it->second );
     242            return &(it->second);
    235243    }
    236244
    237     return( NULL );
     245    return NULL;
    238246}   
    239247
    240248std::vector<std::pair<CStr, CConfigValueSet> > CConfigDB::GetValuesWithPrefix(EConfigNamespace ns, const CStr& prefix)
  • source/ps/GameSetup/GameSetup.cpp

    diff -r 6b3ac7e864ba source/ps/GameSetup/GameSetup.cpp
    a b  
    7676
    7777#include "maths/scripting/JSInterface_Vector3D.h"
    7878
    79 #include "graphics/scripting/JSInterface_Camera.h"
    80 #include "graphics/scripting/JSInterface_LightEnv.h"
    81 
    8279#include "ps/scripting/JSInterface_Console.h"
    8380
    8481#include "gui/GUI.h"
     
    304301    JSI_Vector3D::init();
    305302
    306303    // graphics
    307     JSI_Camera::init();
    308     JSI_LightEnv::init();
    309304    CGameView::ScriptingInit();
    310305
    311306    // renderer
  • source/ps/scripting/JSInterface_Console.cpp

    diff -r 6b3ac7e864ba source/ps/scripting/JSInterface_Console.cpp
    a b  
    1 /* Copyright (C) 2009 Wildfire Games.
     1/* Copyright (C) 2010 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
    44 * 0 A.D. is free software: you can redistribute it and/or modify
     
    4040
    4141JSFunctionSpec JSI_Console::JSI_methods[] =
    4242{
    43     { "write", JSI_Console::writeConsole, 1, 0, 0 },
     43    { "write", JSI_Console::writeConsole, 1, 0 },
    4444    { 0 },
    4545};
    4646
    47 JSBool JSI_Console::getProperty( JSContext* UNUSED(cx), JSObject* UNUSED(obj), jsval id, jsval* vp )
     47JSBool JSI_Console::getProperty(JSContext* UNUSED(cx), JSObject* UNUSED(obj), jsid id, jsval* vp)
    4848{
    49     if( !JSVAL_IS_INT( id ) )
    50         return( JS_TRUE );
     49    if (!JSID_IS_INT(id))
     50        return JS_TRUE;
    5151
    52     int i = JSVAL_TO_INT( id );
     52    int i = JSID_TO_INT(id);
    5353
    54     switch( i )
     54    switch (i)
    5555    {
    5656    case console_visible:
    57         *vp = BOOLEAN_TO_JSVAL( g_Console->IsActive() ); return( JS_TRUE );
     57        *vp = BOOLEAN_TO_JSVAL(g_Console->IsActive());
     58        return JS_TRUE;
    5859    default:
    59         *vp = JSVAL_NULL; return( JS_TRUE );
    60     }   
     60        *vp = JSVAL_NULL;
     61        return JS_TRUE;
     62    }
    6163}
    6264
    63 JSBool JSI_Console::setProperty( JSContext* UNUSED(cx), JSObject* UNUSED(obj), jsval id, jsval* vp )
     65JSBool JSI_Console::setProperty(JSContext* UNUSED(cx), JSObject* UNUSED(obj), jsid id, jsval* vp)
    6466{
    65     if( !JSVAL_IS_INT( id ) )
    66         return( JS_TRUE );
     67    if (!JSID_IS_INT(id))
     68        return JS_TRUE;
    6769
    68     int i = JSVAL_TO_INT( id );
     70    int i = JSID_TO_INT(id);
    6971
    70     switch( i )
     72    switch (i)
    7173    {
    7274    case console_visible:
    7375        try
    7476        {
    75             g_Console->SetVisible( ToPrimitive<bool>( *vp ) );
    76             return( JS_TRUE );
     77            g_Console->SetVisible(ToPrimitive<bool> (*vp));
     78            return JS_TRUE;
    7779        }
    78         catch( PSERROR_Scripting_ConversionFailed )
     80        catch (PSERROR_Scripting_ConversionFailed )
    7981        {
    80             return( JS_TRUE );
     82            return JS_TRUE;
    8183        }
    8284    default:
    83         return( JS_TRUE );
    84     }   
     85        return JS_TRUE;
     86    }
    8587}
    8688
    8789void JSI_Console::init()
    8890{
    89     g_ScriptingHost.DefineCustomObjectType( &JSI_class, NULL, 0, JSI_props, JSI_methods, NULL, NULL );
     91    g_ScriptingHost.DefineCustomObjectType(&JSI_class, NULL, 0, JSI_props, JSI_methods, NULL, NULL);
    9092}
    9193
    92 JSBool JSI_Console::getConsole( JSContext* cx, JSObject* UNUSED(obj), jsval UNUSED(id), jsval* vp )
     94JSBool JSI_Console::getConsole(JSContext* cx, JSObject* UNUSED(obj), jsid UNUSED(id), jsval* vp)
    9395{
    94     JSObject* console = JS_NewObject( cx, &JSI_Console::JSI_class, NULL, NULL );
    95     *vp = OBJECT_TO_JSVAL( console );
    96     return( JS_TRUE );
     96    JSObject* console = JS_NewObject(cx, &JSI_Console::JSI_class, NULL, NULL);
     97    *vp = OBJECT_TO_JSVAL(console);
     98    return JS_TRUE;
    9799}
    98100
    99 JSBool JSI_Console::writeConsole( JSContext* UNUSED(context), JSObject* UNUSED(globalObject), uintN argc, jsval* argv, jsval* UNUSED(rval) )
     101JSBool JSI_Console::writeConsole(JSContext* cx, uintN argc, jsval* vp)
    100102{
    101     debug_assert( argc >= 1 );
     103    UNUSED2(cx);
     104
    102105    CStrW output;
    103     for( unsigned int i = 0; i < argc; i++ )
     106    for (uintN i = 0; i < argc; i++)
    104107    {
    105108        try
    106109        {
    107             CStrW arg = g_ScriptingHost.ValueToUCString( argv[i] );
     110            CStrW arg = g_ScriptingHost.ValueToUCString(JS_ARGV(cx, vp)[i]);
    108111            output += arg;
    109112        }
    110         catch( PSERROR_Scripting_ConversionFailed )
     113        catch (PSERROR_Scripting_ConversionFailed )
    111114        {
    112115        }
    113116    }
    114117
    115118    // TODO: What if the console has been destroyed already?
    116119    if (g_Console)
    117         g_Console->InsertMessage( L"%ls", output.c_str() );
     120        g_Console->InsertMessage(L"%ls", output.c_str());
    118121
    119     return( JS_TRUE );
     122    JS_SET_RVAL(cx, vp, JSVAL_VOID);
     123    return JS_TRUE;
    120124}
  • source/ps/scripting/JSInterface_Console.h

    diff -r 6b3ac7e864ba source/ps/scripting/JSInterface_Console.h
    a b  
    3434    extern JSPropertySpec JSI_props[];
    3535    extern JSFunctionSpec JSI_methods[];
    3636
    37     JSBool getProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp );
    38     JSBool setProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp );
     37    JSBool getProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp);
     38    JSBool setProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp);
    3939
    40     JSBool getConsole( JSContext* context, JSObject* obj, jsval id, jsval* vp );
     40    JSBool getConsole(JSContext* context, JSObject* obj, jsid id, jsval* vp);
    4141
    4242    void init();
    4343
    44     JSBool writeConsole( JSContext* context, JSObject* obj, uintN argc, jsval* argv, jsval* rval );
     44    JSBool writeConsole(JSContext* cx, uintN argc, jsval* vp);
    4545}
    4646
    4747#endif
  • source/ps/scripting/JSInterface_VFS.cpp

    diff -r 6b3ac7e864ba source/ps/scripting/JSInterface_VFS.cpp
    a b  
    2929// shared error handling code
    3030#define JS_CHECK_FILE_ERR(err)\
    3131    /* this is liable to happen often, so don't complain */\
    32     if(err == ERR::VFS_FILE_NOT_FOUND)\
     32    if (err == ERR::VFS_FILE_NOT_FOUND)\
    3333    {\
    34         *rval = JSVAL_NULL;\
    35         return( JS_TRUE );\
     34        JS_SET_RVAL(cx, vp, JSVAL_NULL);\
     35        return JS_TRUE;\
    3636    }\
    3737    /* unknown failure. we return an error (akin to an exception in JS) that
    3838       stops the script to make sure this error is noticed. */\
    39     else if(err < 0)\
    40         return( JS_FALSE );\
     39    else if (err < 0)\
     40        return JS_FALSE;\
    4141    /* else: success */
    4242
    4343
     
    5454        : cx(cx_)
    5555    {
    5656        filename_array = JS_NewArrayObject(cx, 0, NULL);
    57         JS_AddRoot(cx, &filename_array);
     57        JS_AddObjectRoot(cx, &filename_array);
    5858        cur_idx = 0;
    5959    }
    6060
    6161    ~BuildDirEntListState()
    6262    {
    63         JS_RemoveRoot(cx, &filename_array);
     63        JS_RemoveObjectRoot(cx, &filename_array);
    6464    }
    6565};
    6666
     
    8585//
    8686// note: full pathnames of each file/subdirectory are returned,
    8787// ready for use as a "filename" for the other functions.
    88 JSBool JSI_VFS::BuildDirEntList( JSContext* cx, JSObject* UNUSED(obj), uintN argc, jsval* argv, jsval* rval )
     88JSBool JSI_VFS::BuildDirEntList(JSContext* cx, uintN argc, jsval* vp)
    8989{
    9090    //
    9191    // get arguments
    9292    //
    9393
    94     debug_assert( argc >= 1 );
     94    JSU_REQUIRE_MIN_PARAMS(1);
     95
    9596    CStr path;
    96     if( !ToPrimitive<CStr>( cx, argv[0], path ) )
    97         return( JS_FALSE );
     97    if (!ToPrimitive<CStr> (cx, JS_ARGV(cx, vp)[0], path))
     98        return JS_FALSE;
    9899
    99100    CStrW filter_str = L"";
    100     if(argc >= 2)
     101    if (argc >= 2)
    101102    {
    102         if( !ToPrimitive<CStrW>( cx, argv[1], filter_str ) )
    103             return( JS_FALSE );
     103        if (!ToPrimitive<CStrW> (cx, JS_ARGV(cx, vp)[1], filter_str))
     104            return JS_FALSE;
    104105    }
    105106    // convert to const wchar_t*; if there's no filter, pass 0 for speed
    106107    // (interpreted as: "accept all files without comparing").
    107108    const wchar_t* filter = 0;
    108     if(!filter_str.empty())
     109    if (!filter_str.empty())
    109110        filter = filter_str.c_str();
    110111
    111112    bool recursive = false;
    112     if(argc >= 3)
     113    if (argc >= 3)
    113114    {
    114         if( !ToPrimitive<bool>( cx, argv[2], recursive ) )
    115             return( JS_FALSE );
     115        if (!ToPrimitive<bool> (cx, JS_ARGV(cx, vp)[2], recursive))
     116            return JS_FALSE;
    116117    }
    117     int flags = recursive? fs_util::DIR_RECURSIVE : 0;
     118    int flags = recursive ? fs_util::DIR_RECURSIVE : 0;
    118119
    119120
    120121    // build array in the callback function
    121122    BuildDirEntListState state(cx);
    122123    fs_util::ForEachFile(g_VFS, CStrW(path), BuildDirEntListCB, (uintptr_t)&state, filter, flags);
    123124
    124     *rval = OBJECT_TO_JSVAL( state.filename_array );
    125     return( JS_TRUE );
     125    JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(state.filename_array));
     126    return JS_TRUE;
    126127}
    127128
    128129
     
    130131//
    131132// mtime = getFileMTime(filename);
    132133//   filename: VFS filename (may include path)
    133 JSBool JSI_VFS::GetFileMTime( JSContext* cx, JSObject* UNUSED(obj), uintN argc, jsval* argv, jsval* rval )
     134JSBool JSI_VFS::GetFileMTime(JSContext* cx, uintN argc, jsval* vp)
    134135{
    135     debug_assert( argc >= 1 );
     136    JSU_REQUIRE_MIN_PARAMS(1);
     137
    136138    CStr filename;
    137     if( !ToPrimitive<CStr>( cx, argv[0], filename ) )
    138         return( JS_FALSE );
     139    if (!ToPrimitive<CStr> (cx, JS_ARGV(cx, vp)[0], filename))
     140        return JS_FALSE;
    139141
    140142    FileInfo fileInfo;
    141143    LibError err = g_VFS->GetFileInfo(CStrW(filename), &fileInfo);
    142     JS_CHECK_FILE_ERR( err );
     144    JS_CHECK_FILE_ERR(err);
    143145
    144     *rval = ToJSVal( (double)fileInfo.MTime() );
    145     return( JS_TRUE );
     146    JS_SET_RVAL(cx, vp, ToJSVal((double)fileInfo.MTime()));
     147    return JS_TRUE;
    146148}
    147149
    148150
     
    150152//
    151153// size = getFileSize(filename);
    152154//   filename: VFS filename (may include path)
    153 JSBool JSI_VFS::GetFileSize( JSContext* cx, JSObject* UNUSED(obj), uintN argc, jsval* argv, jsval* rval )
     155JSBool JSI_VFS::GetFileSize(JSContext* cx, uintN argc, jsval* vp)
    154156{
    155     debug_assert( argc >= 1 );
     157    JSU_REQUIRE_MIN_PARAMS(1);
     158
    156159    CStr filename;
    157     if( !ToPrimitive<CStr>( cx, argv[0], filename ) )
    158         return( JS_FALSE );
     160    if (!ToPrimitive<CStr> (cx, JS_ARGV(cx, vp)[0], filename))
     161        return JS_FALSE;
    159162
    160163    FileInfo fileInfo;
    161164    LibError err = g_VFS->GetFileInfo(CStrW(filename), &fileInfo);
    162165    JS_CHECK_FILE_ERR(err);
    163166
    164     *rval = ToJSVal( (unsigned)fileInfo.Size() );
    165     return( JS_TRUE );
     167    JS_SET_RVAL(cx, vp, ToJSVal( (unsigned)fileInfo.Size() ));
     168    return JS_TRUE;
    166169}
    167170
    168171
     
    170173//
    171174// contents = readFile(filename);
    172175//   filename: VFS filename (may include path)
    173 JSBool JSI_VFS::ReadFile( JSContext* cx, JSObject* UNUSED(obj), uintN argc, jsval* argv, jsval* rval )
     176JSBool JSI_VFS::ReadFile(JSContext* cx, uintN argc, jsval* vp)
    174177{
    175     debug_assert( argc >= 1 );
     178    JSU_REQUIRE_MIN_PARAMS(1);
     179
    176180    CStr filename;
    177     if( !ToPrimitive<CStr>( cx, argv[0], filename ) )
    178         return( JS_FALSE );
     181    if (!ToPrimitive<CStr> (cx, JS_ARGV(cx, vp)[0], filename))
     182        return JS_FALSE;
    179183
    180     shared_ptr<u8> buf; size_t size;
    181     LibError err = g_VFS->LoadFile( CStrW(filename), buf, size );
     184    shared_ptr<u8> buf;
     185    size_t size;
     186    LibError err = g_VFS->LoadFile(CStrW(filename), buf, size);
    182187    JS_CHECK_FILE_ERR( err );
    183188
    184     CStr contents( (const char*)buf.get(), size );
     189    CStr contents((const char*)buf.get(), size);
    185190
    186191    // Fix CRLF line endings. (This function will only ever be used on text files.)
    187192    contents.Replace("\r\n", "\n");
    188193
    189194    // Decode as UTF-8
    190     *rval = ToJSVal( contents.FromUTF8() );
    191     return( JS_TRUE );
     195    JS_SET_RVAL(cx, vp, ToJSVal( contents.FromUTF8() ));
     196    return JS_TRUE;
    192197}
    193198
    194199
     
    196201//
    197202// lines = readFileLines(filename);
    198203//   filename: VFS filename (may include path)
    199 JSBool JSI_VFS::ReadFileLines( JSContext* cx, JSObject* UNUSED(obj), uintN argc, jsval* argv, jsval* rval )
     204JSBool JSI_VFS::ReadFileLines(JSContext* cx, uintN argc, jsval* vp)
    200205{
    201     debug_assert( argc >= 1 );
     206    JSU_REQUIRE_MIN_PARAMS(1);
     207
    202208    CStr filename;
    203     if( !ToPrimitive<CStr>( cx, argv[0], filename ) )
    204         return( JS_FALSE );
     209    if (!ToPrimitive<CStr> (cx, JS_ARGV(cx, vp)[0], filename))
     210        return (JS_FALSE);
    205211
    206212    //
    207213    // read file
    208214    //
    209215
    210     shared_ptr<u8> buf; size_t size;
    211     LibError err = g_VFS->LoadFile( CStrW(filename), buf, size );
     216    shared_ptr<u8> buf;
     217    size_t size;
     218    LibError err = g_VFS->LoadFile(CStrW(filename), buf, size);
    212219    JS_CHECK_FILE_ERR( err );
    213220
    214     CStr contents( (const char*)buf.get(), size );
     221    CStr contents((const char*)buf.get(), size);
    215222
    216223    // Fix CRLF line endings. (This function will only ever be used on text files.)
    217224    contents.Replace("\r\n", "\n");
     
    220227    // split into array of strings (one per line)
    221228    //
    222229
    223     std::stringstream ss( contents );
     230    std::stringstream ss(contents);
    224231
    225     JSObject* line_array = JS_NewArrayObject( cx, 0, NULL );
    226     JS_AddRoot(cx, &line_array);
     232    JSObject* line_array = JS_NewArrayObject(cx, 0, NULL);
    227233
    228234    std::string line;
    229235    int cur_line = 0;
    230     while( std::getline( ss, line ) )
     236    while (std::getline(ss, line))
    231237    {
    232238        // Decode each line as UTF-8
    233         jsval val = ToJSVal( CStr( line ).FromUTF8() );
    234         JS_SetElement( cx, line_array, cur_line++, &val );
     239        jsval val = ToJSVal(CStr(line).FromUTF8());
     240        JS_SetElement(cx, line_array, cur_line++, &val);
    235241    }
    236242
    237     JS_RemoveRoot(cx, &line_array);
    238 
    239     *rval = OBJECT_TO_JSVAL( line_array );
    240     return( JS_TRUE );
     243    JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL( line_array ));
     244    return JS_TRUE ;
    241245}
    242246
    243247
    244248// vfs_optimizer
    245249
    246 JSBool JSI_VFS::ArchiveBuilderCancel(JSContext* UNUSED(cx), JSObject* UNUSED(obj), uintN argc, jsval* UNUSED(argv), jsval* UNUSED(rval) )
     250JSBool JSI_VFS::ArchiveBuilderCancel(JSContext* cx, uintN argc, jsval* vp)
    247251{
    248     debug_assert( argc == 0 );
     252    UNUSED2(cx);
     253    UNUSED2(argc);
     254
    249255//  vfs_opt_auto_build_cancel();
    250     return( JS_TRUE );
     256
     257    JS_SET_RVAL(cx, vp, JSVAL_VOID);
     258    return JS_TRUE;
    251259}
  • source/ps/scripting/JSInterface_VFS.h

    diff -r 6b3ac7e864ba source/ps/scripting/JSInterface_VFS.h
    a b  
    3838    //
    3939    // note: full pathnames of each file/subdirectory are returned,
    4040    // ready for use as a "filename" for the other functions.
    41     JSBool BuildDirEntList( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );
     41    JSBool BuildDirEntList(JSContext* cx, uintN argc, jsval* vp);
    4242
    4343    // Return time [seconds since 1970] of the last modification to the specified file.
    4444    //
    4545    // mtime = getFileMTime(filename);
    4646    //   filename: VFS filename (may include path)
    47     JSBool GetFileMTime( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );
     47    JSBool GetFileMTime(JSContext* cx, uintN argc, jsval* vp);
    4848
    4949    // Return current size of file.
    5050    //
    5151    // size = getFileSize(filename);
    5252    //   filename: VFS filename (may include path)
    53     JSBool GetFileSize( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );
     53    JSBool GetFileSize(JSContext* cx, uintN argc, jsval* vp);
    5454
    5555    // Return file contents in a string.
    5656    //
    5757    // contents = readFile(filename);
    5858    //   filename: VFS filename (may include path)
    59     JSBool ReadFile( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );
     59    JSBool ReadFile(JSContext* cx, uintN argc, jsval* vp);
    6060
    6161    // Return file contents as an array of lines.
    6262    //
    6363    // lines = readFileLines(filename);
    6464    //   filename: VFS filename (may include path)
    65     JSBool ReadFileLines( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );
     65    JSBool ReadFileLines(JSContext* cx, uintN argc, jsval* vp);
    6666
    6767    // Abort the current archive build operation (no-op if not currently active).
    6868    //
    6969    // archiveBuilderCancel();
    70     JSBool ArchiveBuilderCancel(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );
     70    JSBool ArchiveBuilderCancel(JSContext* cx, uintN argc, jsval* vp);
    7171}
    7272
    7373#endif
  • source/scripting/JSConversions.cpp

    diff -r 6b3ac7e864ba source/scripting/JSConversions.cpp
    a b  
    180180
    181181template<> jsval ToJSVal<double>( const double& Native )
    182182{
    183     return( DOUBLE_TO_JSVAL( JS_NewDouble( g_ScriptingHost.getContext(), Native ) ) );
     183    jsval val = JSVAL_VOID;
     184    JS_NewNumberValue( g_ScriptingHost.getContext(), Native, &val );
     185    return val;
    184186}
    185187
    186188template<> jsval ToJSVal<double>( double& Native )
    187189{
    188     return( DOUBLE_TO_JSVAL( JS_NewDouble( g_ScriptingHost.getContext(), Native ) ) );
     190    jsval val = JSVAL_VOID;
     191    JS_NewNumberValue( g_ScriptingHost.getContext(), Native, &val );
     192    return val;
    189193}
    190194
    191195template<> bool ToPrimitive<double>( JSContext* cx, jsval v, double& Storage )
     
    200204
    201205template<> jsval ToJSVal<float>( const float& Native )
    202206{
    203     return( DOUBLE_TO_JSVAL( JS_NewDouble( g_ScriptingHost.getContext(), Native ) ) );
     207    jsval val = JSVAL_VOID;
     208    JS_NewNumberValue( g_ScriptingHost.getContext(), Native, &val );
     209    return val;
    204210}
    205211
    206212template<> jsval ToJSVal<float>( float& Native )
    207213{
    208     return( DOUBLE_TO_JSVAL( JS_NewDouble( g_ScriptingHost.getContext(), Native ) ) );
     214    jsval val = JSVAL_VOID;
     215    JS_NewNumberValue( g_ScriptingHost.getContext(), Native, &val );
     216    return val;
    209217}
    210218
    211219template<> bool ToPrimitive<float>( JSContext* cx, jsval v, float& Storage )
     
    304312    stringParser.InputTaskType( "string", "_$value_" );
    305313    CParserLine result;
    306314    result.ParseString( stringParser, CStr(Native) );
    307     bool boolResult; int intResult; float floatResult;
     315    bool boolResult;
     316    float floatResult;
    308317
    309318    if( result.GetArgFloat( 0, floatResult ) )
    310     {
    311         if( floatResult == floor( floatResult ) )
    312         {
    313             intResult = (int)floatResult;
    314             if( INT_FITS_IN_JSVAL( intResult ) )
    315                 return( ToJSVal( intResult ) );
    316         }
    317319        return( ToJSVal( floatResult ) );
    318     }
     320
    319321    if( result.GetArgBool( 0, boolResult ) )
    320322        return( BOOLEAN_TO_JSVAL( boolResult ) );
    321323   
  • source/scripting/JSUtil.cpp

    diff -r 6b3ac7e864ba source/scripting/JSUtil.cpp
    a b  
    1919
    2020#include "SpiderMonkey.h"
    2121
    22 jsval jsu_report_param_error(JSContext* cx, jsval* rval)
     22JSBool jsu_report_param_error(JSContext* cx, jsval* vp)
    2323{
    2424    JS_ReportError(cx, "Invalid parameter(s) or count");
    2525
    26     if(rval)
    27         *rval = JSVAL_NULL;
     26    if (vp)
     27        JS_SET_RVAL(cx, vp, JSVAL_NULL);
    2828
    2929    // yes, we had an error, but returning JS_FALSE would cause SpiderMonkey
    3030    // to abort. that would be hard to debug.
  • source/scripting/JSUtil.h

    diff -r 6b3ac7e864ba source/scripting/JSUtil.h
    a b  
    1717
    1818// included from SpiderMonkey.h
    1919
    20 extern jsval jsu_report_param_error(JSContext* cx, jsval* rval);
     20extern JSBool jsu_report_param_error(JSContext* cx, jsval* vp);
    2121
    2222
    2323// consistent argc checking for normal function wrappers: reports an
     
    2525// .. require exact number (most common case)
    2626#define JSU_REQUIRE_PARAMS(exact_number)\
    2727    if(argc != exact_number)\
    28         return jsu_report_param_error(cx, rval);
     28        return jsu_report_param_error(cx, vp);
    2929// .. require 0 params (avoids L4 warning "unused argv param")
    3030#define JSU_REQUIRE_NO_PARAMS()\
    31     UNUSED2(argv);\
    3231    if(argc != 0)\
    33         return jsu_report_param_error(cx, rval);
     32        return jsu_report_param_error(cx, vp);
    3433// .. require a certain range (e.g. due to optional params)
    3534#define JSU_REQUIRE_PARAM_RANGE(min_number, max_number)\
    3635    if(!(min_number <= argc && argc <= max_number))\
    37         return jsu_report_param_error(cx, rval);
     36        return jsu_report_param_error(cx, vp);
    3837// .. require at most a certain count
    3938#define JSU_REQUIRE_MAX_PARAMS(max_number)\
    4039    if(argc > max_number)\
    41         return jsu_report_param_error(cx, rval);
     40        return jsu_report_param_error(cx, vp);
    4241// .. require at least a certain count (rarely needed)
    4342#define JSU_REQUIRE_MIN_PARAMS(min_number)\
    4443    if(argc < min_number)\
    45         return jsu_report_param_error(cx, rval);
     44        return jsu_report_param_error(cx, vp);
    4645
    4746// same as JSU_REQUIRE_PARAMS, but used from C++ functions that are
    4847// a bit further removed from SpiderMonkey, i.e. return a
  • source/scripting/ScriptGlue.cpp

    diff -r 6b3ac7e864ba source/scripting/ScriptGlue.cpp
    a b  
    3131#include "graphics/MapWriter.h"
    3232#include "graphics/Unit.h"
    3333#include "graphics/UnitManager.h"
    34 #include "graphics/scripting/JSInterface_Camera.h"
    35 #include "graphics/scripting/JSInterface_LightEnv.h"
    3634#include "gui/GUIManager.h"
    3735#include "gui/IGUIObject.h"
    3836#include "lib/frequency_filter.h"
     
    109107    js_timer_clients[0].sum.SetToZero();
    110108}
    111109
    112 JSBool StartJsTimer(JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval)
     110JSBool StartJsTimer(JSContext* cx, uintN argc, jsval* vp)
    113111{
    114112    ONCE(InitJsTimers());
    115113
    116114    JSU_REQUIRE_PARAMS(1);
    117     size_t slot = ToPrimitive<size_t>(argv[0]);
     115    size_t slot = ToPrimitive<size_t>(JS_ARGV(cx, vp)[0]);
    118116    if (slot >= MAX_JS_TIMERS)
    119117        return JS_FALSE;
    120118
    121119    js_start_times[slot].SetFromTimer();
     120
     121    JS_SET_RVAL(cx, vp, JSVAL_VOID);
    122122    return JS_TRUE;
    123123}
    124124
    125125
    126 JSBool StopJsTimer(JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval)
     126JSBool StopJsTimer(JSContext* cx, uintN argc, jsval* vp)
    127127{
    128128    JSU_REQUIRE_PARAMS(1);
    129     size_t slot = ToPrimitive<size_t>(argv[0]);
     129    size_t slot = ToPrimitive<size_t>(JS_ARGV(cx, vp)[0]);
    130130    if (slot >= MAX_JS_TIMERS)
    131131        return JS_FALSE;
    132132
     
    135135    now.Subtract(js_timer_overhead);
    136136    BillingPolicy_Default()(&js_timer_clients[slot], js_start_times[slot], now);
    137137    js_start_times[slot].SetToZero();
     138
     139    JS_SET_RVAL(cx, vp, JSVAL_VOID);
    138140    return JS_TRUE;
    139141}
    140142
     
    146148// Immediately ends the current game (if any).
    147149// params:
    148150// returns:
    149 JSBool EndGame(JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval)
     151JSBool EndGame(JSContext* cx, uintN argc, jsval* vp)
    150152{
    151153    JSU_REQUIRE_NO_PARAMS();
    152154
    153155    EndGame();
     156
     157    JS_SET_RVAL(cx, vp, JSVAL_VOID);
    154158    return JS_TRUE;
    155159}
    156160
     
    164168// notes:
    165169// - This value is recalculated once a frame. We take special care to
    166170//   filter it, so it is both accurate and free of jitter.
    167 JSBool GetFps( JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval )
     171JSBool GetFps(JSContext* cx, uintN argc, jsval* vp)
    168172{
    169173    JSU_REQUIRE_NO_PARAMS();
    170174    int freq = 0;
    171175    if (g_frequencyFilter)
    172176        freq = g_frequencyFilter->StableFrequency();
    173     *rval = INT_TO_JSVAL(freq);
     177    JS_SET_RVAL(cx, vp, INT_TO_JSVAL(freq));
    174178    return JS_TRUE;
    175179}
    176180
     
    181185// notes:
    182186// - Exit happens after the current main loop iteration ends
    183187//   (since this only sets a flag telling it to end)
    184 JSBool ExitProgram( JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval )
     188JSBool ExitProgram(JSContext* cx, uintN argc, jsval* vp)
    185189{
    186190    JSU_REQUIRE_NO_PARAMS();
    187191
    188192    kill_mainloop();
    189     return JS_TRUE;
    190 }
    191193
    192 
    193 // Write an indication of total video RAM to console.
    194 // params:
    195 // returns:
    196 // notes:
    197 // - May not be supported on all platforms.
    198 // - Only a rough approximation; do not base low-level decisions
    199 //   ("should I allocate one more texture?") on this.
    200 JSBool WriteVideoMemToConsole( JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval )
    201 {
    202     JSU_REQUIRE_NO_PARAMS();
    203 
    204     const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo();
    205     g_Console->InsertMessage(L"VRAM: total %d", videoInfo->video_mem);
     194    JS_SET_RVAL(cx, vp, JSVAL_VOID);
    206195    return JS_TRUE;
    207196}
    208197
     
    212201// returns:
    213202// notes:
    214203// - Cursors are stored in "art\textures\cursors"
    215 JSBool SetCursor( JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval )
     204JSBool SetCursor(JSContext* cx, uintN argc, jsval* vp)
    216205{
    217206    JSU_REQUIRE_PARAMS(1);
    218     g_CursorName = g_ScriptingHost.ValueToUCString(argv[0]);
     207    g_CursorName = g_ScriptingHost.ValueToUCString(JS_ARGV(cx, vp)[0]);
     208
     209    JS_SET_RVAL(cx, vp, JSVAL_VOID);
    219210    return JS_TRUE;
    220211}
    221212
    222 // Change the LOD bias.
    223 // params: LOD bias [float]
    224 // returns:
    225 // notes:
    226 // - value is as required by GL_TEXTURE_LOD_BIAS.
    227 // - useful for adjusting image "sharpness" (since it affects which mipmap level is chosen)
    228 JSBool _LodBias( JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval )
     213JSBool GetGUIObjectByName(JSContext* cx, uintN argc, jsval* vp)
    229214{
    230215    JSU_REQUIRE_PARAMS(1);
    231216
    232     g_Renderer.SetOptionFloat(CRenderer::OPT_LODBIAS, ToPrimitive<float>(argv[0]));
    233     return JS_TRUE;
    234 }
    235 
    236 
    237 JSBool GetGUIObjectByName(JSContext* cx, JSObject* UNUSED(obj), uintN UNUSED(argc), jsval* argv, jsval* rval)
    238 {
    239217    try
    240218    {
    241         CStr name = ToPrimitive<CStr>(cx, argv[0]);
     219        CStr name = ToPrimitive<CStr>(cx, JS_ARGV(cx, vp)[0]);
    242220        IGUIObject* guiObj = g_GUI->FindObjectByName(name);
    243221        if (guiObj)
    244             *rval = OBJECT_TO_JSVAL(guiObj->GetJSObject());
     222            JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(guiObj->GetJSObject()));
    245223        else
    246             *rval = JSVAL_NULL;
     224            JS_SET_RVAL(cx, vp, JSVAL_NULL);
    247225        return JS_TRUE;
    248226    }
    249227    catch (PSERROR_Scripting&)
     
    270248//   lib/svn_revision.cpp. it is useful to know when attempting to
    271249//   reproduce bugs (the main EXE and PDB should be temporarily reverted to
    272250//   that revision so that they match user-submitted crashdumps).
    273 JSBool GetBuildTimestamp( JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval )
     251JSBool GetBuildTimestamp(JSContext* cx, uintN argc, jsval* vp)
    274252{
    275253    JSU_REQUIRE_MAX_PARAMS(1);
    276254
    277255    char buf[200];
    278256
    279257    // see function documentation
    280     const int mode = argc? JSVAL_TO_INT(argv[0]) : -1;
     258    const int mode = argc? JSVAL_TO_INT(JS_ARGV(cx, vp)[0]) : -1;
    281259    switch(mode)
    282260    {
    283261    case -1:
     
    294272        break;
    295273    }
    296274
    297     *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buf));
     275    JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buf)));
    298276    return JS_TRUE;
    299277}
    300278
     
    311289}
    312290#endif
    313291
    314 JSBool DumpHeaps(JSContext* UNUSED(cx), JSObject* UNUSED(globalObject), uintN UNUSED(argc), jsval* UNUSED(argv), jsval* UNUSED(rval) )
     292JSBool DumpHeaps(JSContext* cx, uintN argc, jsval* vp)
    315293{
     294    UNUSED2(cx);
     295    UNUSED2(argc);
     296
    316297#ifdef DEBUG
    317298    static int i = 0;
    318299
     
    325306#else
    326307    debug_warn(L"DumpHeaps only available in DEBUG mode");
    327308#endif
     309
     310    JS_SET_RVAL(cx, vp, JSVAL_VOID);
    328311    return JS_TRUE;
    329312}
    330313
    331314//-----------------------------------------------------------------------------
    332315
    333316// Is the game paused?
    334 JSBool IsPaused( JSContext* cx, JSObject* UNUSED(globalObject), uintN argc, jsval* argv, jsval* rval )
     317JSBool IsPaused(JSContext* cx, uintN argc, jsval* vp)
    335318{
    336319    JSU_REQUIRE_NO_PARAMS();
    337320
    338     if( !g_Game )
     321    if (!g_Game)
    339322    {
    340         JS_ReportError( cx, "Game is not started" );
     323        JS_ReportError(cx, "Game is not started");
    341324        return JS_FALSE;
    342325    }
    343326
    344     *rval = g_Game->m_Paused ? JSVAL_TRUE : JSVAL_FALSE;
    345     return JS_TRUE ;
     327    JS_SET_RVAL(cx, vp, g_Game->m_Paused ? JSVAL_TRUE : JSVAL_FALSE);
     328    return JS_TRUE;
    346329}
    347330
    348331// Pause/unpause the game
    349 JSBool SetPaused( JSContext* cx, JSObject* UNUSED(globalObject), uintN argc, jsval* argv, jsval* rval )
     332JSBool SetPaused(JSContext* cx, uintN argc, jsval* vp)
    350333{
    351334    JSU_REQUIRE_PARAMS( 1 );
    352335
    353     if( !g_Game )
     336    if (!g_Game)
    354337    {
    355         JS_ReportError( cx, "Game is not started" );
     338        JS_ReportError(cx, "Game is not started");
    356339        return JS_FALSE;
    357340    }
    358341
    359342    try
    360343    {
    361         g_Game->m_Paused = ToPrimitive<bool>( argv[0] );
     344        g_Game->m_Paused = ToPrimitive<bool> (JS_ARGV(cx, vp)[0]);
    362345    }
    363     catch( PSERROR_Scripting_ConversionFailed )
     346    catch (PSERROR_Scripting_ConversionFailed)
    364347    {
    365         JS_ReportError( cx, "Invalid parameter to SetPaused" );
     348        JS_ReportError(cx, "Invalid parameter to SetPaused");
    366349    }
    367350
    368     return  JS_TRUE;
     351    JS_SET_RVAL(cx, vp, JSVAL_VOID);
     352    return JS_TRUE;
    369353}
    370354
    371355
     
    381365// - Extra (reserved for future use, always zero)
    382366//
    383367// we simplify this a bit with a macro:
    384 #define JS_FUNC(script_name, cpp_function, min_params) { script_name, cpp_function, min_params, 0, 0 },
     368#define JS_FUNC(script_name, cpp_function, min_params) { script_name, cpp_function, min_params, 0 },
    385369
    386370JSFunctionSpec ScriptFunctionTable[] =
    387371{
     
    404388    JS_FUNC("exit", ExitProgram, 0)
    405389    JS_FUNC("isPaused", IsPaused, 0)
    406390    JS_FUNC("setPaused", SetPaused, 1)
    407     JS_FUNC("vmem", WriteVideoMemToConsole, 0)
    408     JS_FUNC("_lodBias", _LodBias, 0)
    409391    JS_FUNC("setCursor", SetCursor, 1)
    410392    JS_FUNC("getFPS", GetFps, 0)
    411393    JS_FUNC("getGUIObjectByName", GetGUIObjectByName, 1)
     
    415397    JS_FUNC("dumpHeaps", DumpHeaps, 0)
    416398
    417399    // end of table marker
    418     {0, 0, 0, 0, 0}
     400    {0}
    419401};
    420402#undef JS_FUNC
    421403
     
    424406// property accessors
    425407//-----------------------------------------------------------------------------
    426408
    427 JSBool GetGameView( JSContext* UNUSED(cx), JSObject* UNUSED(obj), jsval UNUSED(id), jsval* vp )
     409JSBool GetGameView(JSContext* UNUSED(cx), JSObject* UNUSED(obj), jsid UNUSED(id), jsval* vp)
    428410{
    429411    if (g_Game)
    430         *vp = OBJECT_TO_JSVAL( g_Game->GetView()->GetScript() );
     412        *vp = OBJECT_TO_JSVAL(g_Game->GetView()->GetScript());
    431413    else
    432414        *vp = JSVAL_NULL;
    433     return( JS_TRUE );
     415    return JS_TRUE;
    434416}
    435417
    436 
    437 JSBool GetRenderer( JSContext* UNUSED(cx), JSObject* UNUSED(obj), jsval UNUSED(id), jsval* vp )
     418JSBool GetRenderer(JSContext* UNUSED(cx), JSObject* UNUSED(obj), jsid UNUSED(id), jsval* vp)
    438419{
    439420    if (CRenderer::IsInitialised())
    440         *vp = OBJECT_TO_JSVAL( g_Renderer.GetScript() );
     421        *vp = OBJECT_TO_JSVAL(g_Renderer.GetScript());
    441422    else
    442423        *vp = JSVAL_NULL;
    443     return( JS_TRUE );
     424    return JS_TRUE;
    444425}
    445426
    446427
     
    455436
    456437JSPropertySpec ScriptGlobalTable[] =
    457438{
    458     { "camera"     , GLOBAL_CAMERA,      JSPROP_PERMANENT, JSI_Camera::getCamera, JSI_Camera::setCamera },
    459439    { "console"    , GLOBAL_CONSOLE,     JSPROP_PERMANENT|JSPROP_READONLY, JSI_Console::getConsole, 0 },
    460     { "lightenv"   , GLOBAL_LIGHTENV,    JSPROP_PERMANENT, JSI_LightEnv::getLightEnv, JSI_LightEnv::setLightEnv },
    461440    { "gameView"   , 0,                  JSPROP_PERMANENT|JSPROP_READONLY, GetGameView, 0 },
    462441    { "renderer"   , 0,                  JSPROP_PERMANENT|JSPROP_READONLY, GetRenderer, 0 },
    463442
  • source/scripting/ScriptableObject.h

    diff -r 6b3ac7e864ba source/scripting/ScriptableObject.h
    a b  
    155155    void Root()
    156156    {
    157157        if( JSVAL_IS_GCTHING( m_Data ) )
    158             JS_AddNamedRoot( g_ScriptingHost.GetContext(), (void*)&m_Data, "ScriptableObjectProperty" );
     158            JS_AddNamedValueRoot( g_ScriptingHost.GetContext(), &m_Data, "ScriptableObjectProperty" );
    159159    }
    160160    void Uproot()
    161161    {
    162162        if( JSVAL_IS_GCTHING( m_Data ))
    163             JS_RemoveRoot( g_ScriptingHost.GetContext(), (void*)&m_Data );
     163            JS_RemoveValueRoot( g_ScriptingHost.GetContext(), &m_Data );
    164164    }
    165165    jsval Get( JSContext* UNUSED(cx), IJSObject* UNUSED(object))
    166166    {
     
    179179template<typename T, bool ReadOnly, typename RType, RType (T::*NativeFunction)( JSContext* cx, uintN argc, jsval* argv )> class CNativeFunction
    180180{
    181181public:
    182     static JSBool JSFunction( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval )
     182    static JSBool JSFunction( JSContext* cx, uintN argc, jsval* vp )
    183183    {
    184         T* Native = ToNative<T>( cx, obj );
     184        T* Native = ToNative<T>( cx, JS_THIS_OBJECT( cx, vp ) );
    185185        if( !Native )
    186             return( JS_TRUE );
     186            return( JS_FALSE );
    187187
    188         *rval = ToJSVal<RType>( (Native->*NativeFunction)( cx, argc, argv ) );
    189 
     188        jsval rval = ToJSVal<RType>( (Native->*NativeFunction)( cx, argc, JS_ARGV(cx, vp) ) );
     189        JS_SET_RVAL( cx, vp, rval );
    190190        return( JS_TRUE );
    191191    }
    192192};
     
    196196class CNativeFunction<T, ReadOnly, void, NativeFunction>
    197197{
    198198public:
    199     static JSBool JSFunction( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* UNUSED(rval) )
     199    static JSBool JSFunction( JSContext* cx, uintN argc, jsval* vp )
    200200    {
    201         T* Native = ToNative<T>( cx, obj );
     201        T* Native = ToNative<T>( cx, JS_THIS_OBJECT( cx, vp ) );
    202202        if( !Native )
    203             return( JS_TRUE );
     203            return( JS_FALSE );
    204204
    205         (Native->*NativeFunction)( cx, argc, argv );
     205        (Native->*NativeFunction)( cx, argc, JS_ARGV(cx, vp) );
    206206
     207        JS_SET_RVAL( cx, vp, JSVAL_VOID );
    207208        return( JS_TRUE );
    208209    }
    209210};
     
    328329    template<typename ReturnType, ReturnType (T::*NativeFunction)( JSContext* cx, uintN argc, jsval* argv )>
    329330        static void AddMethod( const char* Name, uintN MinArgs )
    330331    {
    331         JSFunctionSpec FnInfo = { Name, CNativeFunction<T, ReadOnly, ReturnType, NativeFunction>::JSFunction, (uint8)MinArgs, 0, 0 };
     332        JSFunctionSpec FnInfo = { Name, CNativeFunction<T, ReadOnly, ReturnType, NativeFunction>::JSFunction, (uint8)MinArgs, 0 };
    332333        m_Methods.push_back( FnInfo );
    333334    }
    334335    template<typename PropType> static void AddProperty( const CStrW& PropertyName, PropType T::*Native, bool PropReadOnly = ReadOnly )
     
    373374        {
    374375            m_JS = JS_NewObject( g_ScriptingHost.GetContext(), &JSI_class, NULL, NULL );
    375376            if( m_EngineOwned )
    376                 JS_AddNamedRoot( g_ScriptingHost.GetContext(), (void*)&m_JS, JSI_class.name );
     377                JS_AddNamedObjectRoot( g_ScriptingHost.GetContext(), &m_JS, JSI_class.name );
    377378   
    378379            JS_SetPrivate( g_ScriptingHost.GetContext(), m_JS, (T*)this );
    379380        }
     
    384385        {
    385386            JS_SetPrivate( g_ScriptingHost.GetContext(), m_JS, NULL );
    386387            if( m_EngineOwned )
    387                 JS_RemoveRoot( g_ScriptingHost.GetContext(), &m_JS );
     388                JS_RemoveObjectRoot( g_ScriptingHost.GetContext(), &m_JS );
    388389            m_JS = NULL;
    389390        }
    390391    }
     
    393394    // Functions and data that must be provided to JavaScript
    394395    //
    395396private:
    396     static JSBool JSGetProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp )
     397    static JSBool JSGetProperty( JSContext* cx, JSObject* obj, jsid id, jsval* vp )
    397398    {
    398399        T* Instance = ToNative<T>( cx, obj );
    399400        if( !Instance )
    400401            return( JS_TRUE );
    401402
    402         CStrW PropName = g_ScriptingHost.ValueToUCString( id );
     403        jsval idval;
     404        if( !JS_IdToValue( cx, id, &idval ) )
     405            return( JS_FALSE );
     406
     407        CStrW PropName = g_ScriptingHost.ValueToUCString( idval );
    403408
    404409        if( !Instance->GetProperty( cx, PropName, vp ) )
    405410            return( JS_TRUE );
    406411       
    407412        return( JS_TRUE );
    408413    }
    409     static JSBool JSSetProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp )
     414    static JSBool JSSetProperty( JSContext* cx, JSObject* obj, jsid id, jsval* vp )
    410415    {
    411416        T* Instance = ToNative<T>( cx, obj );
    412417        if( !Instance )
    413418            return( JS_TRUE );
    414419
    415         CStrW PropName = g_ScriptingHost.ValueToUCString( id );
     420        jsval idval;
     421        if( !JS_IdToValue( cx, id, &idval ) )
     422            return( JS_FALSE );
     423
     424        CStrW PropName = g_ScriptingHost.ValueToUCString( idval );
    416425
    417426        Instance->SetProperty( cx, PropName, vp );
    418427
  • source/scripting/ScriptingHost.cpp

    diff -r 6b3ac7e864ba source/scripting/ScriptingHost.cpp
    a b  
    168168
    169169void ScriptingHost::SetObjectProperty_Double(JSObject* object, const char* propertyName, double value)
    170170{
    171     jsdouble* d = JS_NewDouble(m_Context, value);
    172     if (! d)
     171    jsval v;
     172    if (! JS_NewNumberValue(m_Context, value, &v))
    173173        throw PSERROR_Scripting_ConversionFailed();
    174174
    175     jsval v = DOUBLE_TO_JSVAL(d);
    176 
    177175    if (! JS_SetProperty(m_Context, object, propertyName, &v))
    178176        throw PSERROR_Scripting_ConversionFailed();
    179177}
  • source/scripting/SpiderMonkey.h

    diff -r 6b3ac7e864ba source/scripting/SpiderMonkey.h
    a b  
    4545
    4646#include <js/jsapi.h>
    4747
    48 #ifndef NDEBUG
    49 // Used by ScriptingHost::jshook_{script,function}
    50 # include <js/jsdbgapi.h>
    51 #endif
    52 
    5348// include any further required headers here
    5449
    5550#include "JSUtil.h"
  • source/scriptinterface/AutoRooters.cpp

    diff -r 6b3ac7e864ba source/scriptinterface/AutoRooters.cpp
    a b  
    4747    {
    4848        JS_CALL_VALUE_TRACER(trc, m_Vals[i], "AutoGCRooter val");
    4949    }
     50
     51    for (size_t i = 0; i < m_IdArrays.size(); ++i)
     52    {
     53        for (jsint j = 0; j < m_IdArrays[i]->length; ++j)
     54        {
     55            jsval val = JSVAL_VOID;
     56            JS_IdToValue(m_ScriptInterface.GetContext(), m_IdArrays[i]->vector[j], &val);
     57            JS_CALL_VALUE_TRACER(trc, val, "AutoGCRooter id array");
     58        }
     59    }
     60
    5061}
  • source/scriptinterface/AutoRooters.h

    diff -r 6b3ac7e864ba source/scriptinterface/AutoRooters.h
    a b  
    2222
    2323#include "js/jsapi.h"
    2424
    25 // Exception-safety and GC-safety wrapper for JSIdArray
    26 // (TODO: it'd be nicer to use the existing js::AutoIdArray but currently that
    27 // requires a load of semi-private SpiderMonkey headers that cause a load of compile warnings)
    28 class IdArrayWrapper
    29 {
    30     JSContext* m_cx;
    31     JSIdArray* m_ida;
    32 public:
    33     IdArrayWrapper(JSContext* cx, JSIdArray* ida) :
    34         m_cx(cx), m_ida(ida)
    35     {
    36         for (jsint i = 0; i < m_ida->length; ++i)
    37             if (!JS_AddRoot(m_cx, &m_ida->vector[i]))
    38                 debug_warn(L"JS_AddRoot failed");
    39     }
    40     ~IdArrayWrapper()
    41     {
    42         for (jsint i = 0; i < m_ida->length; ++i)
    43             if (!JS_RemoveRoot(m_cx, &m_ida->vector[i]))
    44                 debug_warn(L"JS_RemoveRoot failed");
    45         JS_DestroyIdArray(m_cx, m_ida);
    46     }
    47 };
    48 
    4925/**
    5026 * Helper for rooting large groups of script values.
    5127 * Construct this object, push values into it, and they will all be rooted until this
     
    6137
    6238    void Push(JSObject* obj) { m_Objects.push_back(obj); }
    6339    void Push(jsval val) { m_Vals.push_back(val); }
     40    void Push(JSIdArray* ida) { m_IdArrays.push_back(ida); }
    6441
    6542    void Trace(JSTracer* trc);
    6643private:
     
    6946
    7047    std::vector<JSObject*> m_Objects;
    7148    std::vector<jsval> m_Vals;
     49    std::vector<JSIdArray*> m_IdArrays;
    7250    // TODO: add vectors of other value types
    7351};
    7452
  • source/scriptinterface/ScriptConversions.cpp

    diff -r 6b3ac7e864ba source/scriptinterface/ScriptConversions.cpp
    a b  
    139139    return rval;
    140140}
    141141
    142 template<> jsval ScriptInterface::ToJSVal<i32>(JSContext* cx, const i32& val)
     142template<> jsval ScriptInterface::ToJSVal<i32>(JSContext* UNUSED(cx), const i32& val)
    143143{
    144     if (INT_FITS_IN_JSVAL(val))
    145         return INT_TO_JSVAL(val);
    146     jsval rval = JSVAL_VOID;
    147     JS_NewNumberValue(cx, val, &rval); // ignore return value
    148     return rval;
     144    cassert(JSVAL_INT_BITS == 32);
     145    return INT_TO_JSVAL(val);
    149146}
    150147
    151148template<> jsval ScriptInterface::ToJSVal<u32>(JSContext* cx, const u32& val)
     
    201198    JSObject* obj = JS_NewArrayObject(cx, 0, NULL);
    202199    if (!obj)
    203200        return JSVAL_VOID;
    204     JS_AddRoot(cx, &obj);
    205201    for (size_t i = 0; i < val.size(); ++i)
    206202    {
    207203        jsval el = ScriptInterface::ToJSVal<T>(cx, val[i]);
    208204        JS_SetElement(cx, obj, (jsint)i, &el);
    209205    }
    210     JS_RemoveRoot(cx, &obj);
    211206    return OBJECT_TO_JSVAL(obj);
    212207}
    213208
  • source/scriptinterface/ScriptInterface.cpp

    diff -r 6b3ac7e864ba source/scriptinterface/ScriptInterface.cpp
    a b  
    3939const int RUNTIME_SIZE = 16 * 1024 * 1024; // TODO: how much memory is needed?
    4040const int STACK_CHUNK_SIZE = 8192;
    4141
     42#define signbit(x) ((x) < 0.0 ? true : false) // XXX
     43
    4244#if ENABLE_SCRIPT_PROFILING
    4345#include "js/jsdbgapi.h"
    4446#endif
     
    4951{
    5052    ScriptInterface_impl(const char* nativeScopeName, JSContext* cx);
    5153    ~ScriptInterface_impl();
    52     void Register(const char* name, JSFastNative fptr, uintN nargs);
     54    void Register(const char* name, JSNative fptr, uintN nargs);
    5355
    5456    JSRuntime* m_rt; // NULL if m_cx is shared; non-NULL if we own m_cx
    5557    JSContext* m_cx;
     
    286288        // Threadsafe SpiderMonkey requires that we have a request before doing anything much
    287289        JS_BeginRequest(m_cx);
    288290
    289         m_glob = JS_NewObject(m_cx, &global_class, NULL, NULL);
     291        m_glob = JS_NewGlobalObject(m_cx, &global_class);
    290292        ok = JS_InitStandardClasses(m_cx, m_glob);
    291293
    292294        JS_DefineProperty(m_cx, m_glob, "global", OBJECT_TO_JSVAL(m_glob), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY
     
    296298    m_nativeScope = JS_DefineObject(m_cx, m_glob, nativeScopeName, NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY
    297299            | JSPROP_PERMANENT);
    298300
    299     JS_DefineFunction(m_cx, m_glob, "print", (JSNative)::print,  0, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE);
    300     JS_DefineFunction(m_cx, m_glob, "log",   (JSNative)::logmsg, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE);
    301     JS_DefineFunction(m_cx, m_glob, "warn",  (JSNative)::warn,   1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE);
    302     JS_DefineFunction(m_cx, m_glob, "error", (JSNative)::error,  1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE);
     301    JS_DefineFunction(m_cx, m_glob, "print", ::print,  0, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
     302    JS_DefineFunction(m_cx, m_glob, "log",   ::logmsg, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
     303    JS_DefineFunction(m_cx, m_glob, "warn",  ::warn,   1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
     304    JS_DefineFunction(m_cx, m_glob, "error", ::error,  1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
    303305}
    304306
    305307ScriptInterface_impl::~ScriptInterface_impl()
     
    312314    }
    313315}
    314316
    315 void ScriptInterface_impl::Register(const char* name, JSFastNative fptr, uintN nargs)
     317void ScriptInterface_impl::Register(const char* name, JSNative fptr, uintN nargs)
    316318{
    317     JS_DefineFunction(m_cx, m_nativeScope, name, reinterpret_cast<JSNative>(fptr), nargs, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE);
     319    JS_DefineFunction(m_cx, m_nativeScope, name, fptr, nargs, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
    318320}
    319321
    320322ScriptInterface::ScriptInterface(const char* nativeScopeName, const char* debugName) :
     
    361363        return;
    362364    }
    363365
    364     JSFunction* random = JS_DefineFunction(m->m_cx, JSVAL_TO_OBJECT(math), "random", (JSNative)Math_random, 0,
    365             JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE);
     366    JSFunction* random = JS_DefineFunction(m->m_cx, JSVAL_TO_OBJECT(math), "random", Math_random, 0,
     367            JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
    366368    if (!random)
    367369    {
    368370        LOGERROR(L"ReplaceNondeterministicFunctions: failed to replace Math.random");
     
    372374    JS_SetReservedSlot(m->m_cx, JS_GetFunctionObject(random), 0, PRIVATE_TO_JSVAL(&rng));
    373375}
    374376
    375 void ScriptInterface::Register(const char* name, JSFastNative fptr, size_t nargs)
     377void ScriptInterface::Register(const char* name, JSNative fptr, size_t nargs)
    376378{
    377379    m->Register(name, fptr, (uintN)nargs);
    378380}
     
    387389    return m->m_rt;
    388390}
    389391
    390 bool ScriptInterface::AddRoot(void* ptr, const char* name)
    391 {
    392     return JS_AddNamedRoot(m->m_cx, ptr, name) ? true : false;
    393 }
    394 
    395 bool ScriptInterface::RemoveRoot(void* ptr)
    396 {
    397     return JS_RemoveRoot(m->m_cx, ptr) ? true : false;
    398 }
    399 
    400392AutoGCRooter* ScriptInterface::ReplaceAutoGCRooter(AutoGCRooter* rooter)
    401393{
    402394    debug_assert(m->m_rt); // this class must own the runtime, else the rooter won't work
     
    494486    JSObject* obj;
    495487    if (!JS_ValueToObject(m->m_cx, val, &obj) || obj == NULL)
    496488        return false;
    497     JS_AddRoot(m->m_cx, &obj);
    498489
    499490    // Check that the named function actually exists, to avoid ugly JS error reports
    500491    // when calling an undefined value
    501492    JSBool found;
    502493    if (!JS_HasProperty(m->m_cx, obj, name, &found) || !found)
    503     {
    504         JS_RemoveRoot(m->m_cx, &obj);
    505494        return false;
    506     }
    507495
    508496    JSBool ok = JS_CallFunctionName(m->m_cx, obj, name, (uintN)argc, argv, &ret);
    509     JS_RemoveRoot(m->m_cx, &obj);
    510497
    511498    return ok ? true : false;
    512499}
     
    638625    if (!func)
    639626        return false;
    640627
    641     JS_AddRoot(m->m_cx, &func); // TODO: do we need to root this?
    642628    jsval scriptRval;
    643629    JSBool ok = JS_CallFunction(m->m_cx, NULL, func, 0, NULL, &scriptRval);
    644     JS_RemoveRoot(m->m_cx, &func);
    645630
    646631    return ok ? true : false;
    647632}
     
    782767{
    783768public:
    784769    ValueCloner(ScriptInterface& from, ScriptInterface& to) :
    785         cxFrom(from.GetContext()), cxTo(to.GetContext()), m_RooterFrom(from), m_RooterTo(to)
     770        scriptInterfaceFrom(from), cxFrom(from.GetContext()), cxTo(to.GetContext()), m_RooterFrom(from), m_RooterTo(to)
    786771    {
    787772    }
    788773
     
    792777        if (!JSVAL_IS_GCTHING(val) || JSVAL_IS_NULL(val))
    793778            return val;
    794779
    795         std::map<jsval, jsval>::iterator it = m_Mapping.find(val);
     780        std::map<void*, jsval>::iterator it = m_Mapping.find(JSVAL_TO_GCTHING(val));
    796781        if (it != m_Mapping.end())
    797782            return it->second;
    798783
     
    811796        if (JSVAL_IS_DOUBLE(val))
    812797        {
    813798            jsval rval;
    814             CLONE_REQUIRE(JS_NewNumberValue(cxTo, *JSVAL_TO_DOUBLE(val), &rval), L"JS_NewNumberValue");
    815             m_Mapping[val] = rval;
     799            CLONE_REQUIRE(JS_NewNumberValue(cxTo, JSVAL_TO_DOUBLE(val), &rval), L"JS_NewNumberValue");
    816800            m_RooterTo.Push(rval);
    817801            return rval;
    818802        }
     
    822806            JSString* str = JS_NewUCStringCopyN(cxTo, JS_GetStringChars(JSVAL_TO_STRING(val)), JS_GetStringLength(JSVAL_TO_STRING(val)));
    823807            CLONE_REQUIRE(str, L"JS_NewUCStringCopyN");
    824808            jsval rval = STRING_TO_JSVAL(str);
    825             m_Mapping[val] = rval;
     809            m_Mapping[JSVAL_TO_GCTHING(val)] = rval;
    826810            m_RooterTo.Push(rval);
    827811            return rval;
    828812        }
     
    843827            CLONE_REQUIRE(newObj, L"JS_NewObject");
    844828        }
    845829
    846         m_Mapping[val] = OBJECT_TO_JSVAL(newObj);
     830        m_Mapping[JSVAL_TO_GCTHING(val)] = OBJECT_TO_JSVAL(newObj);
    847831        m_RooterTo.Push(newObj);
    848832
    849833        JSIdArray* ida = JS_Enumerate(cxFrom, JSVAL_TO_OBJECT(val));
    850834        CLONE_REQUIRE(ida, L"JS_Enumerate");
    851835
    852         IdArrayWrapper idaWrapper(cxFrom, ida);
     836        AutoGCRooter idaRooter(scriptInterfaceFrom);
     837        idaRooter.Push(ida);
    853838
    854839        for (jsint i = 0; i < ida->length; ++i)
    855840        {
     
    880865        return OBJECT_TO_JSVAL(newObj);
    881866    }
    882867
     868    ScriptInterface& scriptInterfaceFrom;
    883869    JSContext* cxFrom;
    884870    JSContext* cxTo;
    885     std::map<jsval, jsval> m_Mapping;
     871    std::map<void*, jsval> m_Mapping;
    886872    AutoGCRooter m_RooterFrom;
    887873    AutoGCRooter m_RooterTo;
    888874};
  • source/scriptinterface/ScriptInterface.h

    diff -r 6b3ac7e864ba source/scriptinterface/ScriptInterface.h
    a b  
    223223     */
    224224    template<typename T> static jsval ToJSVal(JSContext* cx, T const& val);
    225225
    226     bool AddRoot(void* ptr, const char* name);
    227     bool RemoveRoot(void* ptr);
    228 
    229226    AutoGCRooter* ReplaceAutoGCRooter(AutoGCRooter* rooter);
    230227
    231228    /**
     
    264261    static JSClass* GetClass(JSContext* cx, JSObject* obj);
    265262    static void* GetPrivate(JSContext* cx, JSObject* obj);
    266263
    267     void Register(const char* name, JSFastNative fptr, size_t nargs);
     264    void Register(const char* name, JSNative fptr, size_t nargs);
    268265    std::auto_ptr<ScriptInterface_impl> m;
    269266
    270267// The nasty macro/template bits are split into a separate file so you don't have to look at them
     
    276273    //   void RegisterFunction(const char* functionName);
    277274    //
    278275    //   template <R, T0..., TR (*fptr) (void* cbdata, T0...)>
    279     //   static JSFastNative call;
     276    //   static JSNative call;
    280277    //
    281278    //   template <R, T0..., JSClass*, TC, TR (TC:*fptr) (T0...)>
    282     //   static JSFastNative callMethod;
     279    //   static JSNative callMethod;
    283280    //
    284281    //   template <dummy, T0...>
    285282    //   static size_t nargs();
  • source/scriptinterface/ScriptTypes.h

    diff -r 6b3ac7e864ba source/scriptinterface/ScriptTypes.h
    a b  
    2525#endif
    2626// (we don't support XP_OS2 or XP_BEOS)
    2727
    28 #include "js/jspubtd.h"
    29 #include "js/jsversion.h"
     28//#include "js/jspubtd.h"
     29//#include "js/jsversion.h"
     30
     31#include "js/jsapi.h"
    3032
    3133#if JS_VERSION != 185
    3234#error Your compiler is trying to use an incorrect version of the SpiderMonkey library.
  • source/scriptinterface/ScriptVal.cpp

    diff -r 6b3ac7e864ba source/scriptinterface/ScriptVal.cpp
    a b  
    2424struct Unrooter
    2525{
    2626    Unrooter(JSContext* cx) : cx(cx) { }
    27     void operator()(jsval* p) { JS_RemoveRoot(cx, p); delete p; }
     27    void operator()(jsval* p) { JS_RemoveValueRoot(cx, p); delete p; }
    2828    JSContext* cx;
    2929};
    3030
    3131CScriptValRooted::CScriptValRooted(JSContext* cx, jsval val)
    3232{
    3333    jsval* p = new jsval(val);
    34     JS_AddNamedRoot(cx, p, "CScriptValRooted");
     34    JS_AddNamedValueRoot(cx, p, "CScriptValRooted");
    3535    m_Val = boost::shared_ptr<jsval>(p, Unrooter(cx));
    3636}
    3737
    3838CScriptValRooted::CScriptValRooted(JSContext* cx, CScriptVal val)
    3939{
    4040    jsval* p = new jsval(val.get());
    41     JS_AddNamedRoot(cx, p, "CScriptValRooted");
     41    JS_AddNamedValueRoot(cx, p, "CScriptValRooted");
    4242    m_Val = boost::shared_ptr<jsval>(p, Unrooter(cx));
    4343}
    4444
    45 jsval CScriptValRooted::get() const
     45const jsval& CScriptValRooted::get() const
     46{
     47    if (!m_Val)
     48        return JSVAL_VOID;
     49    return *m_Val;
     50}
     51
     52jsval& CScriptValRooted::get()
    4653{
    4754    if (!m_Val)
    4855        return JSVAL_VOID;
  • source/scriptinterface/ScriptVal.h

    diff -r 6b3ac7e864ba source/scriptinterface/ScriptVal.h
    a b  
    2929class CScriptVal
    3030{
    3131public:
    32     CScriptVal() : m_Val(0) { }
     32    CScriptVal() : m_Val(JSVAL_VOID) { }
    3333    CScriptVal(jsval val) : m_Val(val) { }
    3434
    35     jsval get() const { return m_Val; }
     35    const jsval& get() const { return m_Val; }
    3636
    3737private:
    3838    jsval m_Val;
     
    4545    CScriptValRooted(JSContext* cx, jsval val);
    4646    CScriptValRooted(JSContext* cx, CScriptVal val);
    4747
    48     jsval get() const;
     48    const jsval& get() const;
     49    jsval& get();
    4950
    5051    bool undefined() const;
    5152
  • source/scriptinterface/tests/test_ScriptConversions.h

    diff -r 6b3ac7e864ba source/scriptinterface/tests/test_ScriptConversions.h
    a b  
    3434        JSContext* cx = script.GetContext();
    3535
    3636        jsval v1 = ScriptInterface::ToJSVal(cx, value);
    37         JS_AddRoot(cx, &v1);
    3837
    3938        // We want to convert values to strings, but can't just call toSource() on them
    4039        // since they might not be objects. So just use uneval.
     
    4241        TS_ASSERT(script.CallFunction(OBJECT_TO_JSVAL(JS_GetGlobalObject(cx)), "uneval", CScriptVal(v1), source));
    4342
    4443        TS_ASSERT_STR_EQUALS(source, expected);
    45 
    46         JS_RemoveRoot(cx, &v1);
    4744    }
    4845
    4946    template <typename T>
     
    5350        JSContext* cx = script.GetContext();
    5451
    5552        jsval v1 = ScriptInterface::ToJSVal(cx, value);
    56         JS_AddRoot(cx, &v1);
    5753
    5854        std::string source;
    5955        TS_ASSERT(script.CallFunction(OBJECT_TO_JSVAL(JS_GetGlobalObject(cx)), "uneval", CScriptVal(v1), source));
     
    6460        T v2 = T();
    6561        TS_ASSERT(ScriptInterface::FromJSVal(script.GetContext(), v1, v2));
    6662        TS_ASSERT_EQUALS(value, v2);
    67 
    68         JS_RemoveRoot(cx, &v1);
    6963    }
    7064
    7165public:
     
    132126
    133127        TS_ASSERT(JSVAL_IS_INT(ScriptInterface::ToJSVal<i32>(cx, 0)));
    134128
    135         TS_ASSERT(JSVAL_IS_INT(ScriptInterface::ToJSVal<i32>(cx, 1073741822))); // JSVAL_INT_MAX-1
    136         TS_ASSERT(JSVAL_IS_INT(ScriptInterface::ToJSVal<i32>(cx, 1073741823))); // JSVAL_INT_MAX
    137         TS_ASSERT(JSVAL_IS_DOUBLE(ScriptInterface::ToJSVal<i32>(cx, 1073741824))); // JSVAL_INT_MAX+1
    138         TS_ASSERT(JSVAL_IS_INT(ScriptInterface::ToJSVal<i32>(cx, -1073741823))); // JSVAL_INT_MIN+1
    139         TS_ASSERT(JSVAL_IS_INT(ScriptInterface::ToJSVal<i32>(cx, -1073741824))); // JSVAL_INT_MIN
    140         TS_ASSERT(JSVAL_IS_DOUBLE(ScriptInterface::ToJSVal<i32>(cx, -1073741825))); // JSVAL_INT_MIN-1
     129        TS_ASSERT(JSVAL_IS_INT(ScriptInterface::ToJSVal<i32>(cx, 2147483646))); // JSVAL_INT_MAX-1
     130        TS_ASSERT(JSVAL_IS_INT(ScriptInterface::ToJSVal<i32>(cx, 2147483647))); // JSVAL_INT_MAX
     131        TS_ASSERT(JSVAL_IS_INT(ScriptInterface::ToJSVal<i32>(cx, -2147483647))); // JSVAL_INT_MIN+1
     132        TS_ASSERT(JSVAL_IS_INT(ScriptInterface::ToJSVal<i32>(cx, -2147483648))); // JSVAL_INT_MIN
    141133
    142134        TS_ASSERT(JSVAL_IS_INT(ScriptInterface::ToJSVal<u32>(cx, 0)));
    143135
    144         TS_ASSERT(JSVAL_IS_INT(ScriptInterface::ToJSVal<u32>(cx, 1073741822))); // JSVAL_INT_MAX-1
    145         TS_ASSERT(JSVAL_IS_INT(ScriptInterface::ToJSVal<u32>(cx, 1073741823))); // JSVAL_INT_MAX
    146         TS_ASSERT(JSVAL_IS_DOUBLE(ScriptInterface::ToJSVal<u32>(cx, 1073741824))); // JSVAL_INT_MAX+1
     136        TS_ASSERT(JSVAL_IS_INT(ScriptInterface::ToJSVal<u32>(cx, 2147483646))); // JSVAL_INT_MAX-1
     137        TS_ASSERT(JSVAL_IS_INT(ScriptInterface::ToJSVal<u32>(cx, 2147483647))); // JSVAL_INT_MAX
     138        TS_ASSERT(JSVAL_IS_DOUBLE(ScriptInterface::ToJSVal<u32>(cx, 2147483648))); // JSVAL_INT_MAX+1
    147139    }
    148140
    149141    void test_nonfinite()
  • source/scriptinterface/tests/test_ScriptInterface.h

    diff -r 6b3ac7e864ba source/scriptinterface/tests/test_ScriptInterface.h
    a b  
    136136        TS_ASSERT(script.Eval(input.c_str(), val));
    137137
    138138        std::string stringified = script.StringifyJSON(val.get());
    139         TS_ASSERT_STR_EQUALS(stringified, "{\n  \"x\":1,\n  \"z\":[2,\n    \"3\xE2\x98\xBA\xEF\xBF\xBD\"\n  ],\n  \"y\":true\n}");
     139        TS_ASSERT_STR_EQUALS(stringified, "{\n  \"x\": 1,\n  \"z\": [\n    2,\n    \"3\xE2\x98\xBA\xEF\xBF\xBD\"\n  ],\n  \"y\": true\n}");
    140140
    141141        val = script.ParseJSON(stringified);
    142142        TS_ASSERT_WSTR_EQUALS(script.ToString(val.get()), L"({x:1, z:[2, \"3\\u263A\\uFFFD\"], y:true})");
  • source/simulation2/scripting/EngineScriptConversions.cpp

    diff -r 6b3ac7e864ba source/simulation2/scripting/EngineScriptConversions.cpp
    a b  
    3737
    3838    // If this is a scripted component, just return the JS object directly
    3939    jsval instance = val->GetJSInstance();
    40     if (instance)
     40    if (!JSVAL_IS_NULL(instance))
    4141        return instance;
    4242
    4343    // Otherwise we need to construct a wrapper object
  • source/simulation2/scripting/ScriptComponent.cpp

    diff -r 6b3ac7e864ba source/simulation2/scripting/ScriptComponent.cpp
    a b  
    2323#include "simulation2/serialization/IDeserializer.h"
    2424
    2525CComponentTypeScript::CComponentTypeScript(ScriptInterface& scriptInterface, jsval instance) :
    26     m_ScriptInterface(scriptInterface), m_Instance(instance)
     26    m_ScriptInterface(scriptInterface), m_Instance(CScriptValRooted(scriptInterface.GetContext(), instance))
    2727{
    28     debug_assert(instance);
    29     m_ScriptInterface.AddRoot(&m_Instance, "CComponentTypeScript.m_Instance");
    30 
    3128    // Cache the property detection for efficiency
    32     m_HasCustomSerialize = m_ScriptInterface.HasProperty(m_Instance, "Serialize");
    33 }
    34 
    35 CComponentTypeScript::~CComponentTypeScript()
    36 {
    37     m_ScriptInterface.RemoveRoot(&m_Instance);
     29    m_HasCustomSerialize = m_ScriptInterface.HasProperty(m_Instance.get(), "Serialize");
    3830}
    3931
    4032void CComponentTypeScript::Init(const CSimContext& UNUSED(context), const CParamNode& paramNode, entity_id_t ent)
    4133{
    42     m_ScriptInterface.SetProperty(m_Instance, "entity", (int)ent, true);
    43     m_ScriptInterface.SetProperty(m_Instance, "template", paramNode, true);
    44     m_ScriptInterface.CallFunctionVoid(m_Instance, "Init");
     34    m_ScriptInterface.SetProperty(m_Instance.get(), "entity", (int)ent, true);
     35    m_ScriptInterface.SetProperty(m_Instance.get(), "template", paramNode, true);
     36    m_ScriptInterface.CallFunctionVoid(m_Instance.get(), "Init");
    4537}
    4638
    4739void CComponentTypeScript::Deinit(const CSimContext& UNUSED(context))
    4840{
    49     m_ScriptInterface.CallFunctionVoid(m_Instance, "Deinit");
     41    m_ScriptInterface.CallFunctionVoid(m_Instance.get(), "Deinit");
    5042}
    5143
    5244void CComponentTypeScript::HandleMessage(const CSimContext& UNUSED(context), const CMessage& msg, bool global)
     
    5547
    5648    CScriptVal msgVal = msg.ToJSValCached(m_ScriptInterface);
    5749
    58     if (!m_ScriptInterface.CallFunctionVoid(m_Instance, name, msgVal))
     50    if (!m_ScriptInterface.CallFunctionVoid(m_Instance.get(), name, msgVal))
    5951        LOGERROR(L"Script message handler %hs failed", name);
    6052}
    6153
     
    6658    if (m_HasCustomSerialize)
    6759    {
    6860        CScriptValRooted val;
    69         if (!m_ScriptInterface.CallFunction(m_Instance, "Serialize", val))
     61        if (!m_ScriptInterface.CallFunction(m_Instance.get(), "Serialize", val))
    7062            LOGERROR(L"Script Serialize call failed");
    7163        serialize.ScriptVal("object", val);
    7264    }
    7365    else
    7466    {
    75         serialize.ScriptVal("object", m_Instance);
     67        serialize.ScriptVal("object", m_Instance.get());
    7668    }
    7769}
    7870
     
    8274
    8375    // Use ScriptObjectAppend so we don't lose the carefully-constructed
    8476    // prototype/parent of this object
    85     deserialize.ScriptObjectAppend("object", m_Instance);
     77    deserialize.ScriptObjectAppend("object", m_Instance.get());
    8678
    87     m_ScriptInterface.SetProperty(m_Instance, "entity", (int)ent, true);
    88     m_ScriptInterface.SetProperty(m_Instance, "template", paramNode, true);
     79    m_ScriptInterface.SetProperty(m_Instance.get(), "entity", (int)ent, true);
     80    m_ScriptInterface.SetProperty(m_Instance.get(), "template", paramNode, true);
    8981}
  • source/simulation2/scripting/ScriptComponent.h

    diff -r 6b3ac7e864ba source/simulation2/scripting/ScriptComponent.h
    a b  
    3535{
    3636public:
    3737    CComponentTypeScript(ScriptInterface& scriptInterface, jsval instance);
    38     ~CComponentTypeScript();
    3938
    40     jsval GetInstance() const { return m_Instance; }
     39    jsval GetInstance() const { return m_Instance.get(); }
    4140
    4241    void Init(const CSimContext& context, const CParamNode& paramNode, entity_id_t ent);
    4342    void Deinit(const CSimContext& context);
     
    5857    R Call(const char* funcname  BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(i, const T, &a)) \
    5958    { \
    6059        R ret; \
    61         if (m_ScriptInterface.CallFunction(m_Instance, funcname  BOOST_PP_ENUM_TRAILING_PARAMS(i, a), ret)) \
     60        if (m_ScriptInterface.CallFunction(m_Instance.get(), funcname  BOOST_PP_ENUM_TRAILING_PARAMS(i, a), ret)) \
    6261            return ret; \
    6362        LOGERROR(L"Error calling component script function %hs", funcname); \
    6463        return R(); \
     
    6665    BOOST_PP_IF(i, template<, ) BOOST_PP_ENUM_PARAMS(i, typename T) BOOST_PP_IF(i, >, ) \
    6766    void CallVoid(const char* funcname  BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(i, const T, &a)) \
    6867    { \
    69         if (m_ScriptInterface.CallFunctionVoid(m_Instance, funcname  BOOST_PP_ENUM_TRAILING_PARAMS(i, a))) \
     68        if (m_ScriptInterface.CallFunctionVoid(m_Instance.get(), funcname  BOOST_PP_ENUM_TRAILING_PARAMS(i, a))) \
    7069            return; \
    7170        LOGERROR(L"Error calling component script function %hs", funcname); \
    7271    }
     
    7574
    7675private:
    7776    ScriptInterface& m_ScriptInterface;
    78     jsval m_Instance;
     77    CScriptValRooted m_Instance;
    7978    bool m_HasCustomSerialize;
    8079
    8180    NONCOPYABLE(CComponentTypeScript);
  • source/simulation2/serialization/BinarySerializer.cpp

    diff -r 6b3ac7e864ba source/simulation2/serialization/BinarySerializer.cpp
    a b  
    3232# pragma warning(disable:4800)  // forcing value to bool 'true' or 'false' (performance warning)
    3333#endif
    3434
    35 #include "js/jsobj.h"
     35//#include "js/jsobj.h"
    3636
    3737#if MSC_VERSION
    3838# pragma warning(pop)
     
    100100
    101101        // Find all properties (ordered by insertion time)
    102102
    103         // JS_Enumerate is a bit slow (lots of memory allocation), so do the enumeration manually
    104         // (based on the code from JS_Enumerate, using the probably less stable JSObject API):
    105         //
    106         // Correction: Actually array_enumerate returns an incorrect num_properties so we can't
    107         // trust it and have to iterate over all ids before we know how many there are, so
    108         // actually this probably isn't any faster than JS_Enumerate. Also it's less compatible
    109         // with future JSAPI updates. This probably wasn't a great idea.
    110 
    111103        // (Note that we don't do any rooting, because we assume nothing is going to trigger GC.
    112104        // I'm not absolute certain that's necessarily a valid assumption.)
    113105
    114         jsval iter_state, num_properties;
    115         if (!obj->enumerate(cx, JSENUMERATE_INIT, &iter_state, &num_properties))
    116             throw PSERROR_Serialize_ScriptError("enumerate INIT failed");
    117         debug_assert(JSVAL_IS_INT(num_properties));
    118         debug_assert(JSVAL_TO_INT(num_properties) >= 0);
     106        JSIdArray* ida = JS_Enumerate(cx, obj);
     107        if (!ida)
     108            throw PSERROR_Serialize_ScriptError("JS_Enumerate failed");
    119109
    120         std::vector<jsid> ids;
    121         ids.reserve(JSVAL_TO_INT(num_properties));
     110        m_Serializer.NumberU32_Unbounded("num props", (uint32_t)ida->length);
    122111
    123         while (true)
     112        for (jsint i = 0; i < ida->length; ++i)
    124113        {
    125             jsval id;
    126             if (!obj->enumerate(cx, JSENUMERATE_NEXT, &iter_state, &id))
    127                 throw PSERROR_Serialize_ScriptError("enumerate NEXT failed");
    128 
    129             if (JSVAL_IS_NULL(iter_state))
    130                 break;
    131 
    132             ids.push_back(id);
    133         }
    134 
    135         m_Serializer.NumberU32_Unbounded("num props", (uint32_t)ids.size());
    136 
    137         for (size_t i = 0; i < ids.size(); ++i)
    138         {
    139             jsval id = ids[i];
     114            jsid id = ida->vector[i];
    140115
    141116            jsval idval, propval;
    142117
     
    183158        {
    184159            debug_assert(JSVAL_IS_DOUBLE(val));
    185160            m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_DOUBLE);
    186             jsdouble* dbl = JSVAL_TO_DOUBLE(val);
    187             m_Serializer.NumberDouble_Unbounded("value", *dbl);
     161            m_Serializer.NumberDouble_Unbounded("value", JSVAL_TO_DOUBLE(val));
    188162        }
    189163        break;
    190164    }
  • source/simulation2/serialization/StdDeserializer.cpp

    diff -r 6b3ac7e864ba source/simulation2/serialization/StdDeserializer.cpp
    a b  
    4646{
    4747    std::pair<std::map<u32, JSObject*>::iterator, bool> it = m_ScriptBackrefs.insert(std::make_pair((u32)m_ScriptBackrefs.size()+1, obj));
    4848    debug_assert(it.second);
    49     if (!JS_AddRoot(m_ScriptInterface.GetContext(), (void*)&it.first->second))
     49    if (!JS_AddObjectRoot(m_ScriptInterface.GetContext(), &it.first->second))
    5050        throw PSERROR_Deserialize_ScriptError("JS_AddRoot failed");
    5151}
    5252
     
    6363    std::map<u32, JSObject*>::iterator it = m_ScriptBackrefs.begin();
    6464    for (; it != m_ScriptBackrefs.end(); ++it)
    6565    {
    66         if (!JS_RemoveRoot(m_ScriptInterface.GetContext(), (void*)&it->second))
     66        if (!JS_RemoveObjectRoot(m_ScriptInterface.GetContext(), &it->second))
    6767            throw PSERROR_Deserialize_ScriptError("JS_RemoveRoot failed");
    6868    }
    6969    m_ScriptBackrefs.clear();
  • source/simulation2/system/ComponentManager.cpp

    diff -r 6b3ac7e864ba source/simulation2/system/ComponentManager.cpp
    a b  
    100100CComponentManager::~CComponentManager()
    101101{
    102102    ResetState();
    103 
    104     // Release GC roots
    105     std::map<ComponentTypeId, ComponentType>::iterator it = m_ComponentTypesById.begin();
    106     for (; it != m_ComponentTypesById.end(); ++it)
    107         if (it->second.type == CT_Script)
    108             m_ScriptInterface.RemoveRoot(&it->second.ctor);
    109103}
    110104
    111105void CComponentManager::LoadComponentTypes()
     
    194188            }
    195189        }
    196190
    197         // Clean up the old component type
    198         componentManager->m_ScriptInterface.RemoveRoot(&componentManager->m_ComponentTypesById[cid].ctor);
    199 
    200         // Remove its old message subscriptions
     191        // Remove the old component type's message subscriptions
    201192        std::map<MessageTypeId, std::vector<ComponentTypeId> >::iterator it;
    202193        for (it = componentManager->m_LocalMessageSubscriptions.begin(); it != componentManager->m_LocalMessageSubscriptions.end(); ++it)
    203194        {
     
    228219    }
    229220
    230221    // Construct a new ComponentType, using the wrapper's alloc functions
    231     ComponentType ct = { CT_Script, iid, ctWrapper.alloc, ctWrapper.dealloc, cname, schema, ctor.get() };
     222    ComponentType ct = {
     223        CT_Script,
     224        iid,
     225        ctWrapper.alloc,
     226        ctWrapper.dealloc,
     227        cname,
     228        schema,
     229        CScriptValRooted(componentManager->m_ScriptInterface.GetContext(), ctor)
     230    };
    232231    componentManager->m_ComponentTypesById[cid] = ct;
    233232
    234233    componentManager->m_CurrentComponent = cid; // needed by Subscribe
    235234
    236     // Stop the ctor getting GCed
    237     componentManager->m_ScriptInterface.AddRoot(&componentManager->m_ComponentTypesById[cid].ctor, "ComponentType ctor");
    238     // TODO: check carefully that roots will never get leaked etc
    239 
    240235
    241236    // Find all the ctor prototype's On* methods, and subscribe to the appropriate messages:
    242237
     
    285280        for (; eit != comps.end(); ++eit)
    286281        {
    287282            jsval instance = eit->second->GetJSInstance();
    288             if (instance)
     283            if (!JSVAL_IS_NULL(instance))
    289284                componentManager->m_ScriptInterface.SetPrototype(instance, proto.get());
    290285        }
    291286    }
     
    458453void CComponentManager::RegisterComponentType(InterfaceId iid, ComponentTypeId cid, AllocFunc alloc, DeallocFunc dealloc,
    459454        const char* name, const std::string& schema)
    460455{
    461     ComponentType c = { CT_Native, iid, alloc, dealloc, name, schema, 0 };
     456    ComponentType c = { CT_Native, iid, alloc, dealloc, name, schema, CScriptValRooted() };
    462457    m_ComponentTypesById.insert(std::make_pair(cid, c));
    463458    m_ComponentTypeIdsByName[name] = cid;
    464459}
     
    466461void CComponentManager::RegisterComponentTypeScriptWrapper(InterfaceId iid, ComponentTypeId cid, AllocFunc alloc,
    467462        DeallocFunc dealloc, const char* name, const std::string& schema)
    468463{
    469     ComponentType c = { CT_ScriptWrapper, iid, alloc, dealloc, name, schema, 0 };
     464    ComponentType c = { CT_ScriptWrapper, iid, alloc, dealloc, name, schema, CScriptValRooted() };
    470465    m_ComponentTypesById.insert(std::make_pair(cid, c));
    471466    m_ComponentTypeIdsByName[name] = cid;
    472467    // TODO: merge with RegisterComponentType
     
    584579    std::map<entity_id_t, IComponent*>& emap2 = m_ComponentsByTypeId[cid];
    585580
    586581    // If this is a scripted component, construct the appropriate JS object first
    587     jsval obj = 0;
     582    jsval obj = JSVAL_NULL;
    588583    if (ct.type == CT_Script)
    589584    {
    590         obj = m_ScriptInterface.CallConstructor(ct.ctor);
    591         if (!obj)
     585        obj = m_ScriptInterface.CallConstructor(ct.ctor.get());
     586        if (JSVAL_IS_VOID(obj))
    592587        {
    593588            LOGERROR(L"Script component constructor failed");
    594589            return NULL;
  • source/simulation2/system/ComponentManager.h

    diff -r 6b3ac7e864ba source/simulation2/system/ComponentManager.h
    a b  
    6666        DeallocFunc dealloc;
    6767        std::string name;
    6868        std::string schema; // RelaxNG fragment
    69         jsval ctor; // only valid if type == CT_Script
     69        CScriptValRooted ctor; // only valid if type == CT_Script
    7070    };
    7171
    7272public:
  • source/simulation2/system/IComponent.cpp

    diff -r 6b3ac7e864ba source/simulation2/system/IComponent.cpp
    a b  
    4040
    4141jsval IComponent::GetJSInstance() const
    4242{
    43     return 0;
     43    return JSVAL_NULL;
    4444}
  • source/simulation2/system/InterfaceScripted.h

    diff -r 6b3ac7e864ba source/simulation2/system/InterfaceScripted.h
    a b  
    4545
    4646#define DEFINE_INTERFACE_METHOD_0(scriptname, rettype, classname, methodname) \
    4747    { scriptname, \
    48         reinterpret_cast<JSNative>(static_cast<JSFastNative>(ScriptInterface::callMethod<rettype, &class_##classname, classname, &classname::methodname>)), \
     48        ScriptInterface::callMethod<rettype, &class_##classname, classname, &classname::methodname>, \
    4949        0, \
    50         JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT|JSFUN_FAST_NATIVE, 0 },
     50        JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT },
    5151
    5252#define DEFINE_INTERFACE_METHOD_1(scriptname, rettype, classname, methodname, arg1) \
    5353    { scriptname, \
    54         reinterpret_cast<JSNative>(static_cast<JSFastNative>(ScriptInterface::callMethod<rettype, arg1, &class_##classname, classname, &classname::methodname>)), \
     54        ScriptInterface::callMethod<rettype, arg1, &class_##classname, classname, &classname::methodname>, \
    5555        1, \
    56         JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT|JSFUN_FAST_NATIVE, 0 },
     56        JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT },
    5757
    5858#define DEFINE_INTERFACE_METHOD_2(scriptname, rettype, classname, methodname, arg1, arg2) \
    5959    { scriptname, \
    60         reinterpret_cast<JSNative>(static_cast<JSFastNative>(ScriptInterface::callMethod<rettype, arg1, arg2, &class_##classname, classname, &classname::methodname>)), \
     60        ScriptInterface::callMethod<rettype, arg1, arg2, &class_##classname, classname, &classname::methodname>, \
    6161        2, \
    62         JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT|JSFUN_FAST_NATIVE, 0 },
     62        JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT },
    6363
    6464#define DEFINE_INTERFACE_METHOD_3(scriptname, rettype, classname, methodname, arg1, arg2, arg3) \
    6565    { scriptname, \
    66         reinterpret_cast<JSNative>(static_cast<JSFastNative>(ScriptInterface::callMethod<rettype, arg1, arg2, arg3, &class_##classname, classname, &classname::methodname>)), \
     66        ScriptInterface::callMethod<rettype, arg1, arg2, arg3, &class_##classname, classname, &classname::methodname>, \
    6767        3, \
    68         JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT|JSFUN_FAST_NATIVE, 0 },
     68        JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT },
    6969
    7070#define DEFINE_INTERFACE_METHOD_4(scriptname, rettype, classname, methodname, arg1, arg2, arg3, arg4) \
    7171    { scriptname, \
    72         reinterpret_cast<JSNative>(static_cast<JSFastNative>(ScriptInterface::callMethod<rettype, arg1, arg2, arg3, arg4, &class_##classname, classname, &classname::methodname>)), \
     72        ScriptInterface::callMethod<rettype, arg1, arg2, arg3, arg4, &class_##classname, classname, &classname::methodname>, \
    7373        4, \
    74         JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT|JSFUN_FAST_NATIVE, 0 },
     74        JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT },
    7575
    7676#define DEFINE_INTERFACE_METHOD_5(scriptname, rettype, classname, methodname, arg1, arg2, arg3, arg4, arg5) \
    7777    { scriptname, \
    78         reinterpret_cast<JSNative>(static_cast<JSFastNative>(ScriptInterface::callMethod<rettype, arg1, arg2, arg3, arg4, arg5, &class_##classname, classname, &classname::methodname>)), \
     78        ScriptInterface::callMethod<rettype, arg1, arg2, arg3, arg4, arg5, &class_##classname, classname, &classname::methodname>, \
    7979        5, \
    80         JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT|JSFUN_FAST_NATIVE, 0 },
     80        JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT },
    8181
    8282#endif // INCLUDED_INTERFACE_SCRIPTED
  • source/simulation2/tests/test_ComponentManager.h

    diff -r 6b3ac7e864ba source/simulation2/tests/test_ComponentManager.h
    a b  
    325325    {
    326326        CSimContext context;
    327327        CComponentManager man(context);
     328        ScriptTestSetup(man.m_ScriptInterface);
    328329        man.LoadComponentTypes();
    329330        TS_ASSERT(man.LoadScript(L"simulation/components/test-entityid.js"));
    330331
     
    334335        man.AddComponent(ent1, man.LookupCID("TestScript1A"), noParam);
    335336        man.AddComponent(ent2, man.LookupCID("TestScript1A"), noParam);
    336337
    337         TestLogger log;
    338338        TS_ASSERT_EQUALS(static_cast<ICmpTest1*> (man.QueryInterface(ent1, IID_Test1))->GetX(), (int)ent1);
    339339        TS_ASSERT_EQUALS(static_cast<ICmpTest1*> (man.QueryInterface(ent2, IID_Test1))->GetX(), (int)ent2);
    340         TS_ASSERT_WSTR_CONTAINS(log.GetOutput(), L"this.entity is read-only");
    341340    }
    342341
    343342    void test_script_QueryInterface()
     
    632631    {
    633632        CSimContext context;
    634633        CComponentManager man(context);
     634        ScriptTestSetup(man.m_ScriptInterface);
    635635        man.LoadComponentTypes();
    636636        TS_ASSERT(man.LoadScript(L"simulation/components/test-serialize.js"));
    637637
  • source/simulation2/tests/test_Serializer.h

    diff -r 6b3ac7e864ba source/simulation2/tests/test_Serializer.h
    a b  
    372372        const char stream[] = "\x02" // SCRIPT_TYPE_ARRAY
    373373                    "\x04\0\0\0" // num props
    374374                    "\x01\0\0\0" "0\0" // "0"
    375                     "\x05" "\x00\0\0\xC0" // SCRIPT_TYPE_INT -1073741824 (JS_INT_MIN)
     375                    "\x05" "\0\0\0\x80" // SCRIPT_TYPE_INT -2147483648 (JS_INT_MIN)
    376376                    "\x01\0\0\0" "1\0" // "1"
    377                     "\x06" "\0\0\x40\0\0\0\xD0\xC1" // SCRIPT_TYPE_DOUBLE -1073741825 (JS_INT_MIN-1)
     377                    "\x06" "\0\0\x20\0\0\0\xE0\xC1" // SCRIPT_TYPE_DOUBLE -2147483649 (JS_INT_MIN-1)
    378378                    "\x01\0\0\0" "2\0" // "2"
    379                     "\x05" "\xFF\xFF\xFF\x3F" // SCRIPT_TYPE_INT 1073741823
     379                    "\x05" "\xFF\xFF\xFF\x7F" // SCRIPT_TYPE_INT 2147483647 (JS_INT_MAX)
    380380                    "\x01\0\0\0" "3\0" // "3"
    381                     "\x06" "\0\0\0\0\0\0\xD0\x41" // SCRIPT_TYPE_DOUBLE 1073741824
     381                    "\x06" "\0\0\0\0\0\0\xE0\x41" // SCRIPT_TYPE_DOUBLE 2147483648 (JS_INT_MAX+1)
    382382        ;
    383383
    384         helper_script_roundtrip("numbers", "[-1073741824, -1073741825, 1.073741823e+9, 1073741824]",
    385                 "[-1073741824, -1073741825, 1073741823, 1073741824]", sizeof(stream) - 1, stream);
     384        helper_script_roundtrip("numbers", "[-2147483648, -2147483649, 2.147483647e+9, 2147483648]",
     385                "[-2147483648, -2147483649, 2147483647, 2147483648]", sizeof(stream) - 1, stream);
    386386    }
    387387
    388388    void test_script_exceptions()
  • source/sound/JSI_Sound.cpp

    diff -r 6b3ac7e864ba source/sound/JSI_Sound.cpp
    a b  
    2828{
    2929    m_Handle = snd_open(g_VFS, pathname);
    3030
    31     // special-case to avoid throwing exceptions if quickstart has
    32     // disabled sound: set a flag queried by Construct; the object will
    33     // then immediately be freed.
    34     if (m_Handle == ERR::AGAIN)
     31    // if open failed, we still have to return a valid non-null object to
     32    // the script, so just reset the handle to 0 so all subsequent method
     33    // calls will do nothing
     34    if (m_Handle < 0)
    3535    {
    36         m_SoundDisabled = true;
     36        m_Handle = 0;
    3737        return;
    3838    }
    39     m_SoundDisabled = false;
    40 
    41     // if open failed, raise an exception - it's the only way to
    42     // report errors, since we're in the ctor and don't want to move
    43     // the open call elsewhere (by requiring an explicit open() call).
    44     if (m_Handle < 0)
    45         throw std::exception(); // caught by JSI_Sound::Construct.
    4639
    4740    (void)snd_set_pos(m_Handle, 0,0,0, true);
    4841}
     
    190183    return "[object Sound: " + CStr(h_filename(m_Handle).string()) + "]";
    191184}
    192185
    193 JSBool JSI_Sound::Construct(JSContext* cx, JSObject* UNUSED(obj), uintN argc, jsval* argv, jsval* rval)
     186JSBool JSI_Sound::Construct(JSContext* cx, uintN argc, jsval* vp)
    194187{
    195     debug_assert(argc >= 1); // FIXME
     188    JSU_REQUIRE_MIN_PARAMS(1);
     189
    196190    CStrW filename;
    197     if (! ToPrimitive<CStrW>(cx, argv[0], filename))
     191    if (! ToPrimitive<CStrW>(cx, JS_ARGV(cx, vp)[0], filename))
    198192        return JS_FALSE;
    199193
    200     try
    201     {
    202         JSI_Sound* newObject = new JSI_Sound(filename);
    203 
    204         // somewhat of a hack to avoid throwing exceptions if
    205         // sound was disabled due to quickstart. see JSI_Sound().
    206         if (newObject->m_SoundDisabled)
    207         {
    208             delete newObject;
    209             *rval = JSVAL_NULL;
    210             return JS_TRUE;
    211         }
    212 
    213         newObject->m_EngineOwned = false;
    214         *rval = OBJECT_TO_JSVAL(newObject->GetScript());
    215     }
    216     catch (std::exception)
    217     {
    218         // failed, but this can happen easily enough that we don't want to
    219         // return JS_FALSE (since that stops the script).
    220         *rval = JSVAL_NULL;
    221     }
     194    JSI_Sound* newObject = new JSI_Sound(filename);
     195    newObject->m_EngineOwned = false;
     196    JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(newObject->GetScript()));
    222197
    223198    return JS_TRUE;
    224199}
  • source/sound/JSI_Sound.h

    diff -r 6b3ac7e864ba source/sound/JSI_Sound.h
    a b  
    4848
    4949    // Script-bound functions
    5050
    51     CStr ToString( JSContext* cx, uintN argc, jsval* argv );
     51    CStr ToString(JSContext* cx, uintN argc, jsval* argv);
    5252
    5353    // start playing the sound (one-shot).
    5454    // it will automatically be freed when done.
    55     bool Play( JSContext* cx, uintN argc, jsval* argv );
     55    bool Play(JSContext* cx, uintN argc, jsval* argv);
    5656
    5757    // request the sound be played until free() is called. returns immediately.
    58     bool Loop( JSContext* cx, uintN argc, jsval* argv );
     58    bool Loop(JSContext* cx, uintN argc, jsval* argv);
    5959
    6060    // stop sound if currently playing and free resources.
    6161    // doesn't need to be called unless played via loop() -
    6262    // sounds are freed automatically when done playing.
    63     bool Free( JSContext* cx, uintN argc, jsval* argv );
     63    bool Free(JSContext* cx, uintN argc, jsval* argv);
    6464
    65     bool SetGain( JSContext* cx, uintN argc, jsval* argv );
     65    bool SetGain(JSContext* cx, uintN argc, jsval* argv);
    6666
    67     bool SetPitch( JSContext* cx, uintN argc, jsval* argv );
     67    bool SetPitch(JSContext* cx, uintN argc, jsval* argv);
    6868
    69     bool SetPosition( JSContext* cx, uintN argc, jsval* argv );
     69    bool SetPosition(JSContext* cx, uintN argc, jsval* argv);
    7070
    71     bool Fade ( JSContext* cx, uintN argc, jsval* argv );
     71    bool Fade(JSContext* cx, uintN argc, jsval* argv);
    7272
    73     static JSBool Construct( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );
     73    static JSBool Construct(JSContext* cx, uintN argc, jsval* vp);
    7474
    7575    static void ScriptingInit();
    76 
    77 private:
    78     bool m_SoundDisabled;   // see constructor and JSI_Sound::Construct
    7976};
    8077
    8178#endif  // #ifndef INCLUDED_JSI_SOUND