@@ -5,7 +5,6 @@ use crate::js_array::handle_array_static_method;
55use crate :: js_bigint:: bigint_constructor;
66use crate :: js_date:: { handle_date_method, handle_date_static_method} ;
77use crate :: js_number:: { handle_number_instance_method, handle_number_prototype_method, handle_number_static_method, number_constructor} ;
8- use crate :: js_os:: handle_os_method;
98use crate :: js_string:: { string_from_char_code, string_from_code_point, string_raw} ;
109use crate :: {
1110 JSError , JSErrorKind , PropertyKey , Value ,
@@ -678,6 +677,58 @@ pub fn evaluate_expr<'gc>(mc: &MutationContext<'gc>, env: &JSObjectDataPtr<'gc>,
678677 evaluate_expr ( mc, env, else_expr)
679678 }
680679 }
680+ Expr :: Object ( properties) => {
681+ let obj = crate :: core:: new_js_object_data ( mc) ;
682+ if let Some ( obj_val) = env_get ( env, "Object" ) {
683+ if let Value :: Object ( obj_ctor) = & * obj_val. borrow ( ) {
684+ if let Some ( proto_val) = obj_get_key_value ( obj_ctor, & "prototype" . into ( ) ) ? {
685+ if let Value :: Object ( proto) = & * proto_val. borrow ( ) {
686+ obj. borrow_mut ( mc) . prototype = Some ( * proto) ;
687+ }
688+ }
689+ }
690+ }
691+
692+ for ( key_expr, val_expr, is_computed) in properties {
693+ let key_val = evaluate_expr ( mc, env, key_expr) ?;
694+ let val = evaluate_expr ( mc, env, val_expr) ?;
695+
696+ let key_str = match key_val {
697+ Value :: String ( s) => utf16_to_utf8 ( & s) ,
698+ Value :: Number ( n) => n. to_string ( ) ,
699+ Value :: Boolean ( b) => b. to_string ( ) ,
700+ Value :: BigInt ( b) => b. to_string ( ) ,
701+ Value :: Undefined => "undefined" . to_string ( ) ,
702+ Value :: Null => "null" . to_string ( ) ,
703+ _ => "object" . to_string ( ) ,
704+ } ;
705+ obj_set_key_value ( mc, & obj, & PropertyKey :: from ( key_str) , val) ?;
706+ }
707+ Ok ( Value :: Object ( obj) )
708+ }
709+ Expr :: Array ( elements) => {
710+ let arr_obj = crate :: core:: new_js_object_data ( mc) ;
711+ if let Some ( arr_val) = env_get ( env, "Array" ) {
712+ if let Value :: Object ( arr_ctor) = & * arr_val. borrow ( ) {
713+ if let Some ( proto_val) = obj_get_key_value ( arr_ctor, & "prototype" . into ( ) ) ? {
714+ if let Value :: Object ( proto) = & * proto_val. borrow ( ) {
715+ arr_obj. borrow_mut ( mc) . prototype = Some ( * proto) ;
716+ }
717+ }
718+ }
719+ }
720+
721+ let mut len = 0 ;
722+ for ( i, elem_opt) in elements. iter ( ) . enumerate ( ) {
723+ if let Some ( elem) = elem_opt {
724+ let val = evaluate_expr ( mc, env, elem) ?;
725+ obj_set_key_value ( mc, & arr_obj, & i. to_string ( ) . into ( ) , val) ?;
726+ }
727+ len = i + 1 ;
728+ }
729+ obj_set_key_value ( mc, & arr_obj, & "length" . into ( ) , Value :: Number ( len as f64 ) ) ?;
730+ Ok ( Value :: Object ( arr_obj) )
731+ }
681732 Expr :: Function ( name, params, body) => {
682733 let mut body_clone = body. clone ( ) ;
683734 Ok ( evaluate_function_expression ( mc, env, name. clone ( ) , params, & mut body_clone) ?)
@@ -729,12 +780,50 @@ pub fn evaluate_expr<'gc>(mc: &MutationContext<'gc>, env: &JSObjectDataPtr<'gc>,
729780 }
730781 } else if let Some ( method_name) = name. strip_prefix ( "console." ) {
731782 crate :: js_console:: handle_console_method ( mc, method_name, & eval_args, env)
732- } else if let Some ( method) = name. strip_prefix ( "os.path." ) {
733- let this_val = this_val. clone ( ) . unwrap_or ( Value :: Object ( * env) ) ;
734- Ok ( handle_os_method ( mc, this_val, method, & eval_args, env) . map_err ( EvalError :: Js ) ?)
735783 } else if let Some ( method) = name. strip_prefix ( "os." ) {
736- let this_val = this_val. clone ( ) . unwrap_or ( Value :: Object ( * env) ) ;
737- Ok ( handle_os_method ( mc, this_val, method, & eval_args, env) . map_err ( EvalError :: Js ) ?)
784+ #[ cfg( feature = "os" ) ]
785+ {
786+ let this_val = this_val. clone ( ) . unwrap_or ( Value :: Object ( * env) ) ;
787+ Ok ( crate :: js_os:: handle_os_method ( mc, this_val, method, & eval_args, env) . map_err ( EvalError :: Js ) ?)
788+ }
789+ #[ cfg( not( feature = "os" ) ) ]
790+ {
791+ Err ( EvalError :: Js ( raise_eval_error ! (
792+ "os module not enabled. Recompile with --features os"
793+ ) ) )
794+ }
795+ } else if let Some ( method) = name. strip_prefix ( "std." ) {
796+ #[ cfg( feature = "std" ) ]
797+ {
798+ match method {
799+ "sprintf" => Ok ( crate :: js_std:: sprintf:: handle_sprintf_call ( & eval_args) . map_err ( EvalError :: Js ) ?) ,
800+ "tmpfile" => Ok ( crate :: js_std:: tmpfile:: create_tmpfile ( mc) . map_err ( EvalError :: Js ) ?) ,
801+ _ => Err ( EvalError :: Js ( raise_eval_error ! ( format!( "std method '{}' not implemented" , method) ) ) ) ,
802+ }
803+ }
804+ #[ cfg( not( feature = "std" ) ) ]
805+ {
806+ Err ( EvalError :: Js ( raise_eval_error ! (
807+ "std module not enabled. Recompile with --features std"
808+ ) ) )
809+ }
810+ } else if let Some ( method) = name. strip_prefix ( "tmp." ) {
811+ #[ cfg( feature = "std" ) ]
812+ {
813+ if let Some ( Value :: Object ( this_obj) ) = this_val {
814+ Ok ( crate :: js_std:: tmpfile:: handle_file_method ( & this_obj, method, & eval_args) . map_err ( EvalError :: Js ) ?)
815+ } else {
816+ Err ( EvalError :: Js ( raise_eval_error ! (
817+ "TypeError: tmp method called on incompatible receiver"
818+ ) ) )
819+ }
820+ }
821+ #[ cfg( not( feature = "std" ) ) ]
822+ {
823+ Err ( EvalError :: Js ( raise_eval_error ! (
824+ "std module (tmpfile) not enabled. Recompile with --features std"
825+ ) ) )
826+ }
738827 } else if let Some ( method) = name. strip_prefix ( "BigInt.prototype." ) {
739828 let this_v = this_val. clone ( ) . unwrap_or ( Value :: Undefined ) ;
740829 Ok ( crate :: js_bigint:: handle_bigint_object_method ( this_v, method, & eval_args) . map_err ( EvalError :: Js ) ?)
0 commit comments