diff --git a/runtime/ejs-date.c b/runtime/ejs-date.c index 46c04f5b..1684f6e2 100644 --- a/runtime/ejs-date.c +++ b/runtime/ejs-date.c @@ -25,6 +25,23 @@ _ejs_date_unix_now () return OBJECT_TO_EJSVAL(rv); } +ejsval +ejs_date_new (long tstamp) { + EJSDate* rv = _ejs_gc_new (EJSDate); + + _ejs_init_object ((EJSObject*)rv, _ejs_Date_prototype, &_ejs_Date_specops); + + /* recover timezone first */ + gettimeofday (&rv->tv, &rv->tz); + + /* convert and assign milliseconds afterwards */ + rv->tv.tv_sec = tstamp / 1000; + rv->tv.tv_usec = (tstamp % 1000) * 1000; + rv->valid = EJS_TRUE; + + return OBJECT_TO_EJSVAL(rv); +} + double _ejs_date_get_time (EJSDate *date) { diff --git a/runtime/ejs-date.h b/runtime/ejs-date.h index a0f11bd9..793cf6fa 100644 --- a/runtime/ejs-date.h +++ b/runtime/ejs-date.h @@ -19,9 +19,10 @@ typedef struct { struct timezone tz; } EJSDate; - EJS_BEGIN_DECLS +ejsval ejs_date_new (long tstamp); + extern ejsval _ejs_Date; extern ejsval _ejs_Date_prototype; extern EJSSpecOps _ejs_Date_specops; diff --git a/runtime/ejs-jsobjc.h b/runtime/ejs-jsobjc.h index 9df831f4..2c728c91 100644 --- a/runtime/ejs-jsobjc.h +++ b/runtime/ejs-jsobjc.h @@ -69,6 +69,8 @@ +(CKValue*)nsStringValue:(NSString*)str; +(CKValue*)utf8StringValue:(const char*)str; ++(CKValue*)nsDateValue:(NSDate*)date; + +(CKValue*)valueWithJSValue:(ejsval)val; -(ejsval)jsValue; @@ -148,9 +150,11 @@ -(BOOL)isFunction; -(BOOL)isConstructor; -(BOOL)isArray; +-(BOOL)isDate; -(jsuint)arrayLength; -(uint16_t)functionArity;; +-(jslong)dateTimestamp; -(CKObject*)prototype; diff --git a/runtime/ejs-jsobjc.m b/runtime/ejs-jsobjc.m index 5456bec9..42ff01e3 100644 --- a/runtime/ejs-jsobjc.m +++ b/runtime/ejs-jsobjc.m @@ -7,6 +7,7 @@ #include "ejs-objc.h" #include "ejs-object.h" #include "ejs-array.h" +#include "ejs-date.h" #include "ejs-string.h" #define SPEW(x) @@ -243,6 +244,13 @@ +(id)utf8StringValue:(const char*)str return [[[CKValue alloc] initWithJSValue:STRING_TO_EJSVAL([[CKString stringWithUTF8CString:str] jsString])] autorelease]; } ++(id)nsDateValue:(NSDate*)date +{ + ejsval jsDate = ejs_date_new (floor(date.timeIntervalSince1970 * 1000.0)); + return [[[CKValue alloc] initWithJSValue:jsDate] autorelease]; +} + + +(id)valueWithJSValue:(ejsval)val { return [[[CKValue alloc] initWithJSValue:val] autorelease]; @@ -486,6 +494,11 @@ -(BOOL)isArray return _obj->ops == &_ejs_Array_specops || _obj->ops == &_ejs_sparsearray_specops; } +-(BOOL)isDate +{ + return _obj->ops == &_ejs_Date_specops; +} + -(jsuint)arrayLength { return ((EJSArray*)_obj)->array_length; @@ -499,6 +512,12 @@ -(uint16_t)functionArity #endif } +-(jslong)dateTimestamp +{ + EJSDate *date = (EJSDate*)_obj; + return (date->tv.tv_sec * 1000) + (date->tv.tv_usec / 1000); +} + -(CKObject*)prototype { ejsval p = _ejs_object_getprop (OBJECT_TO_EJSVAL(_obj), _ejs_atom_prototype); diff --git a/runtime/ejs-objc.m b/runtime/ejs-objc.m index 4a4fc66d..4c1ce8a4 100644 --- a/runtime/ejs-objc.m +++ b/runtime/ejs-objc.m @@ -440,6 +440,10 @@ -(NSString*) description return [CKValue nsStringValue:(NSString*)objc_id]; } + if ([objc_id isKindOfClass:[NSDate class]]) { + return [CKValue nsDateValue:(NSDate*)objc_id]; + } + CKObject* ctor_obj = NULL; Class return_class = object_getClass (objc_id); @@ -523,6 +527,13 @@ -(NSString*) description return [NSArray arrayWithArray:nsarray]; } +static NSDate* +marshal_jsdate_as_nsdate (CKObject *o) +{ + NSTimeInterval tstamp = [o dateTimestamp] / 1000.0; + return [NSDate dateWithTimeIntervalSince1970:tstamp]; +} + static ejsval invokeSelectorFromJS (ejsval env, ejsval _this, uint32_t argc, ejsval* args) { @@ -619,7 +630,10 @@ -(NSString*) description // let's assume we marshal this as an NSArray for now... XXX arg_ptr = marshal_jsarray_as_nsarray (o); } + if ([o isDate]) + arg_ptr = marshal_jsdate_as_nsdate (o); } + SPEW(NSLog (@"arg %d: object marshalling of %@", i, arg_ptr);) } else { diff --git a/runtime/ejs-types.h b/runtime/ejs-types.h index b1d9bec4..f8f67792 100644 --- a/runtime/ejs-types.h +++ b/runtime/ejs-types.h @@ -23,6 +23,7 @@ typedef unsigned long long uint64_t; typedef int32_t jsint; typedef uint32_t jsuint; +typedef long jslong; typedef double jsdouble; typedef uint16_t jschar;