1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
10 typedef v8::Value JSValue;
11 typedef v8::Handle<v8::Object> JSObject;
12 typedef v8::Handle<v8::Object> JSFXObject;
13 typedef unsigned JSBool;
19 const wchar_t* string;
20 FX_BYTE t; //0:double 1:str
26 v8::AccessorGetterCallback pPropGet;
27 v8::AccessorSetterCallback pPropPut;
33 v8::FunctionCallback pMethodCall;
37 typedef CFX_WideString JS_ErrorString;
39 #define JS_TRUE (unsigned)1
40 #define JS_FALSE (unsigned)0
43 #define CJS_PointsArray CFX_ArrayTemplate<float>
44 #define CJS_IntArray CFX_ArrayTemplate<int>
46 /* ====================================== PUBLIC DEFINE SPEC ============================================== */
47 #define JS_WIDESTRING(widestring) L###widestring
49 #define OBJ_PROP_PARAMS IFXJS_Context* cc, CJS_PropValue& vp, JS_ErrorString& sError
50 #define OBJ_METHOD_PARAMS IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, JS_ErrorString& sError
51 #define BEGIN_JS_STATIC_CONST(js_class_name) JSConstSpec js_class_name::JS_Class_Consts[] = {
52 #define JS_STATIC_CONST_ENTRY_NUMBER(const_name, pValue) {JS_WIDESTRING(const_name), pValue, L"", 0},
53 #define JS_STATIC_CONST_ENTRY_STRING(const_name, pValue) {JS_WIDESTRING(const_name), 0, JS_WIDESTRING(pValue), 1},
54 #define END_JS_STATIC_CONST() {0, 0, 0, 0}};
56 #define BEGIN_JS_STATIC_PROP(js_class_name) JSPropertySpec js_class_name::JS_Class_Properties[] = {
57 #define JS_STATIC_PROP_ENTRY(prop_name) {JS_WIDESTRING(prop_name), get_##prop_name##_static, set_##prop_name##_static},
58 #define END_JS_STATIC_PROP() {0, 0, 0}};
60 #define BEGIN_JS_STATIC_METHOD(js_class_name) JSMethodSpec js_class_name::JS_Class_Methods[] = {
61 #define JS_STATIC_METHOD_ENTRY(method_name, nargs) {JS_WIDESTRING(method_name), method_name##_static, nargs},
62 #define END_JS_STATIC_METHOD() {0, 0, 0}};
63 #define MEMLEAKCHECK_1() ((void)0)
64 #define MEMLEAKCHECK_2(main_name, sub_name) ((void)0)
69 #define MEMLEAKCHECK_1() \
71 _CrtMemCheckpoint(&state1);
73 #define MEMLEAKCHECK_2(main_name,sub_name) \
75 _CrtMemCheckpoint(&state2);\
77 _CrtMemDifference(&diff,&state1,&state2);\
78 if (diff.lSizes[_NORMAL_BLOCK] > 0)\
80 TRACE("Detected normal block memory leaks in JS Module! [%s.%s]\n",#main_name,#sub_name);\
81 _CrtMemDumpStatistics(&diff);\
84 #define MEMLEAKCHECK_1() ((void)0)
85 #define MEMLEAKCHECK_2(main_name,sub_name) ((void)0)
89 /* ======================================== PROP CALLBACK ============================================ */
91 #define JS_STATIC_PROP_GET(prop_name, class_name)\
92 static void get_##prop_name##_static(JS_PROPGET_ARGS)\
94 v8::Isolate* isolate = info.GetIsolate();\
95 v8::Local<v8::Context> context = isolate->GetCurrentContext();\
96 v8::Local<v8::Value> v = context->GetEmbedderData(1);\
97 ASSERT(!v.IsEmpty());\
98 if(v.IsEmpty()) return;\
99 v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(v);\
100 IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)field->Value();\
101 IFXJS_Context* cc = pRuntime->GetCurrentContext();\
102 CJS_PropValue value(isolate);\
103 value.StartGetting();\
104 CJS_Object* pJSObj = (CJS_Object*)JS_GetPrivate(isolate,info.Holder());\
105 ASSERT(pJSObj != NULL);\
106 class_name* pObj = (class_name*)pJSObj->GetEmbedObject();\
107 ASSERT(pObj != NULL);\
108 JS_ErrorString sError;\
109 FX_BOOL bRet = FALSE;\
111 bRet = pObj->prop_name(cc, value, sError);\
112 MEMLEAKCHECK_2(class_name, prop_name);\
115 info.GetReturnValue().Set((v8::Handle<v8::Value>)value);\
120 CFX_ByteString cbName;\
121 cbName.Format("%s.%s", #class_name, #prop_name);\
122 JS_Error(NULL,CFX_WideString::FromLocal(cbName), sError);\
127 #define JS_STATIC_PROP_SET(prop_name, class_name)\
128 static void set_##prop_name##_static(JS_PROPPUT_ARGS)\
130 v8::Isolate* isolate = info.GetIsolate();\
131 v8::Local<v8::Context> context = isolate->GetCurrentContext();\
132 v8::Local<v8::Value> v = context->GetEmbedderData(1);\
133 ASSERT(!v.IsEmpty());\
134 if(v.IsEmpty()) return;\
135 v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(v);\
136 IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)field->Value();\
137 IFXJS_Context* cc = pRuntime->GetCurrentContext();\
138 CJS_PropValue propValue(CJS_Value(isolate,value,VT_unknown));\
139 propValue.StartSetting();\
140 CJS_Object* pJSObj = (CJS_Object*)JS_GetPrivate(isolate,info.Holder());\
141 ASSERT(pJSObj != NULL);\
142 class_name* pObj = (class_name*)pJSObj->GetEmbedObject();\
143 ASSERT(pObj != NULL);\
144 JS_ErrorString sError;\
145 FX_BOOL bRet = FALSE;\
147 bRet = pObj->prop_name(cc, propValue, sError);\
148 MEMLEAKCHECK_2(class_name, prop_name);\
155 CFX_ByteString cbName;\
156 cbName.Format("%s.%s", #class_name, #prop_name);\
157 JS_Error(NULL,CFX_WideString::FromLocal(cbName), sError);\
162 #define JS_STATIC_PROP(prop_name, class_name)\
163 JS_STATIC_PROP_GET(prop_name, class_name);\
164 JS_STATIC_PROP_SET(prop_name, class_name)
166 /* ========================================= METHOD CALLBACK =========================================== */
168 #define JS_STATIC_METHOD(method_name, class_name)\
169 static void method_name##_static(JS_METHOD_ARGS)\
171 v8::Isolate* isolate = info.GetIsolate();\
172 v8::Local<v8::Context> context = isolate->GetCurrentContext();\
173 v8::Local<v8::Value> v = context->GetEmbedderData(1);\
174 ASSERT(!v.IsEmpty());\
175 if(v.IsEmpty()) return;\
176 v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(v);\
177 IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)field->Value();\
178 IFXJS_Context* cc = pRuntime->GetCurrentContext();\
179 CJS_Parameters parameters;\
180 for (unsigned int i = 0; i<(unsigned int)info.Length(); i++)\
182 parameters.push_back(CJS_Value(isolate, info[i], VT_unknown));\
184 CJS_Value valueRes(isolate);\
185 CJS_Object* pJSObj = (CJS_Object *)JS_GetPrivate(isolate,info.Holder());\
186 ASSERT(pJSObj != NULL);\
187 class_name* pObj = (class_name*)pJSObj->GetEmbedObject();\
188 ASSERT(pObj != NULL);\
189 JS_ErrorString sError;\
190 FX_BOOL bRet = FALSE;\
192 bRet = pObj->method_name(cc, parameters, valueRes, sError);\
193 MEMLEAKCHECK_2(class_name, method_name);\
196 info.GetReturnValue().Set(valueRes.ToJSValue());\
201 CFX_ByteString cbName;\
202 cbName.Format("%s.%s", #class_name, #method_name);\
203 JS_Error(NULL, CFX_WideString::FromLocal(cbName), sError);\
208 /* ===================================== JS CLASS =============================================== */
210 #define DECLARE_JS_CLASS(js_class_name) \
211 static JSBool JSConstructor(IFXJS_Context* cc, JSFXObject obj,JSFXObject global);\
212 static JSBool JSDestructor(JSFXObject obj);\
213 static int Init(IJS_Runtime* pRuntime, FXJSOBJTYPE eObjType);\
214 static void GetConsts(JSConstSpec*& pConsts, int& nSize);\
215 static void GetProperties(JSPropertySpec*& pProperties, int& nSize);\
216 static void GetMethods(JSMethodSpec*& pMethods, int& nSize);\
217 static JSConstSpec JS_Class_Consts[];\
218 static JSPropertySpec JS_Class_Properties[];\
219 static JSMethodSpec JS_Class_Methods[];\
220 static const wchar_t* m_pClassName
222 #define IMPLEMENT_JS_CLASS_RICH(js_class_name, class_alternate, class_name) \
223 const wchar_t* js_class_name::m_pClassName = JS_WIDESTRING(class_name);\
224 JSBool js_class_name::JSConstructor(IFXJS_Context* cc, JSFXObject obj, JSFXObject global)\
226 CJS_Object* pObj = FX_NEW js_class_name(obj);\
227 pObj->SetEmbedObject(FX_NEW class_alternate(pObj));\
228 JS_SetPrivate(NULL,obj,(void*)pObj); \
229 pObj->InitInstance(cc);\
233 JSBool js_class_name::JSDestructor(JSFXObject obj) \
235 js_class_name* pObj = (js_class_name*)JS_GetPrivate(NULL,obj);\
236 ASSERT(pObj != NULL);\
237 pObj->ExitInstance();\
242 int js_class_name::Init(IJS_Runtime* pRuntime, FXJSOBJTYPE eObjType)\
244 int nObjDefnID = JS_DefineObj(pRuntime, js_class_name::m_pClassName, eObjType, JSConstructor, JSDestructor, 0);\
245 if (nObjDefnID >= 0)\
247 for (int j=0, szj=sizeof(JS_Class_Properties)/sizeof(JSPropertySpec)-1; j<szj; j++)\
249 if (JS_DefineObjProperty(pRuntime, nObjDefnID, JS_Class_Properties[j].pName, JS_Class_Properties[j].pPropGet, JS_Class_Properties[j].pPropPut) < 0) return -1;\
251 for (int k=0, szk=sizeof(JS_Class_Methods)/sizeof(JSMethodSpec)-1; k<szk; k++)\
253 if (JS_DefineObjMethod(pRuntime, nObjDefnID,JS_Class_Methods[k].pName, JS_Class_Methods[k].pMethodCall, JS_Class_Methods[k].nParamNum) < 0) return -1;\
259 void js_class_name::GetConsts(JSConstSpec*& pConsts, int& nSize)\
261 pConsts = JS_Class_Consts;\
262 nSize = sizeof(JS_Class_Consts) / sizeof(JSConstSpec) - 1;\
264 void js_class_name::GetProperties(JSPropertySpec*& pProperties, int& nSize)\
266 pProperties = JS_Class_Properties;\
267 nSize = sizeof(JS_Class_Properties) / sizeof(JSPropertySpec) - 1;\
269 void js_class_name::GetMethods(JSMethodSpec*& pMethods, int& nSize)\
271 pMethods = JS_Class_Methods;\
272 nSize = sizeof(JS_Class_Methods) / sizeof(JSMethodSpec) - 1;\
275 #define IMPLEMENT_JS_CLASS(js_class_name, class_name) IMPLEMENT_JS_CLASS_RICH(js_class_name, class_name, class_name)
277 /* ======================================== CONST CLASS ============================================ */
279 #define DECLARE_JS_CLASS_CONST() \
280 static int Init(IJS_Runtime* pRuntime, FXJSOBJTYPE eObjType);\
281 static void GetConsts(JSConstSpec*& pConsts, int& nSize);\
282 static JSConstSpec JS_Class_Consts[];\
283 static const wchar_t* m_pClassName
285 #define IMPLEMENT_JS_CLASS_CONST(js_class_name, class_name) \
286 const wchar_t* js_class_name::m_pClassName = JS_WIDESTRING(class_name);\
287 int js_class_name::Init(IJS_Runtime* pRuntime, FXJSOBJTYPE eObjType)\
289 int nObjDefnID = JS_DefineObj(pRuntime, js_class_name::m_pClassName, eObjType, NULL, NULL, 0);\
292 for (int i=0, sz=sizeof(JS_Class_Consts)/sizeof(JSConstSpec)-1; i<sz; i++)\
294 if (JS_Class_Consts[i].t == 0)\
296 if (JS_DefineObjConst(pRuntime, nObjDefnID, JS_Class_Consts[i].pName, JS_NewNumber(pRuntime,JS_Class_Consts[i].number)) < 0) return -1;\
300 if (JS_DefineObjConst(pRuntime, nObjDefnID, JS_Class_Consts[i].pName, JS_NewString(pRuntime,JS_Class_Consts[i].string)) < 0) return -1;\
307 void js_class_name::GetConsts(JSConstSpec*& pConsts, int& nSize)\
309 pConsts = JS_Class_Consts;\
310 nSize = sizeof(JS_Class_Consts)/sizeof(JSConstSpec)-1;\
313 /* ===================================== SPECIAL JS CLASS =============================================== */
315 #define DECLARE_SPECIAL_JS_CLASS(js_class_name) \
316 static JSBool JSConstructor(IFXJS_Context* cc, JSFXObject obj, JSFXObject global);\
317 static JSBool JSDestructor(JSFXObject obj);\
318 static void GetConsts(JSConstSpec*& pConsts, int& nSize);\
319 static void GetProperties(JSPropertySpec*& pProperties, int& nSize);\
320 static void GetMethods(JSMethodSpec*& pMethods, int& nSize);\
321 static JSConstSpec JS_Class_Consts[];\
322 static JSPropertySpec JS_Class_Properties[];\
323 static JSMethodSpec JS_Class_Methods[];\
324 static int Init(IJS_Runtime* pRuntime, FXJSOBJTYPE eObjType);\
325 static const wchar_t* m_pClassName;\
326 static void queryprop_##js_class_name##_static(JS_PROPQUERY_ARGS);\
327 static void getprop_##js_class_name##_static(JS_NAMED_PROPGET_ARGS);\
328 static void putprop_##js_class_name##_static(JS_NAMED_PROPPUT_ARGS);\
329 static void delprop_##js_class_name##_static(JS_PROPDEL_ARGS)
331 #define IMPLEMENT_SPECIAL_JS_CLASS(js_class_name, class_alternate, class_name) \
332 const wchar_t * js_class_name::m_pClassName = JS_WIDESTRING(class_name);\
333 void js_class_name::queryprop_##js_class_name##_static(JS_PROPQUERY_ARGS)\
335 v8::Isolate* isolate = info.GetIsolate();\
336 v8::String::Utf8Value utf8_value(property);\
337 CFX_WideString propname = CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());\
338 CJS_Object* pJSObj = (CJS_Object*)JS_GetPrivate(isolate,info.Holder());\
339 ASSERT(pJSObj != NULL);\
340 class_alternate* pObj = (class_alternate*)pJSObj->GetEmbedObject();\
341 ASSERT(pObj != NULL);\
342 FX_BOOL bRet = FALSE;\
344 bRet = pObj->QueryProperty((FX_LPCWSTR)propname);\
345 MEMLEAKCHECK_2(class_name, (FX_LPCWSTR)prop_name);\
348 info.GetReturnValue().Set(0x004);\
353 info.GetReturnValue().Set(0);\
358 void js_class_name::getprop_##js_class_name##_static(JS_NAMED_PROPGET_ARGS)\
360 v8::Isolate* isolate = info.GetIsolate();\
361 v8::Local<v8::Context> context = isolate->GetCurrentContext();\
362 v8::Local<v8::Value> v = context->GetEmbedderData(1);\
363 ASSERT(!v.IsEmpty());\
364 if(v.IsEmpty()) return;\
365 v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(v);\
366 IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)field->Value();\
367 IFXJS_Context* cc = pRuntime->GetCurrentContext();\
368 v8::String::Utf8Value utf8_value(property);\
369 CFX_WideString propname = CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());\
370 CJS_PropValue value(isolate);\
371 value.StartGetting();\
372 CJS_Object* pJSObj = (CJS_Object*)JS_GetPrivate(isolate,info.Holder());\
373 ASSERT(pJSObj != NULL);\
374 class_alternate* pObj = (class_alternate*)pJSObj->GetEmbedObject();\
375 ASSERT(pObj != NULL);\
376 JS_ErrorString sError;\
377 FX_BOOL bRet = FALSE;\
379 bRet = pObj->DoProperty(cc, (FX_LPCWSTR)propname, value, sError);\
380 MEMLEAKCHECK_2(class_name, L"GetProperty");\
383 info.GetReturnValue().Set((v8::Handle<v8::Value>)value);\
388 CFX_ByteString cbName;\
389 cbName.Format("%s.%s", #class_name, L"GetProperty");\
390 JS_Error(NULL,CFX_WideString::FromLocal(cbName), sError);\
393 JS_Error(NULL,L"GetProperty", L"Embeded object not found!");\
396 void js_class_name::putprop_##js_class_name##_static(JS_NAMED_PROPPUT_ARGS)\
398 v8::Isolate* isolate = info.GetIsolate();\
399 v8::Local<v8::Context> context = isolate->GetCurrentContext();\
400 v8::Local<v8::Value> v = context->GetEmbedderData(1);\
401 ASSERT(!v.IsEmpty());\
402 if(v.IsEmpty()) return;\
403 v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(v);\
404 IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)field->Value();\
405 IFXJS_Context* cc = pRuntime->GetCurrentContext();\
406 v8::String::Utf8Value utf8_value(property);\
407 CFX_WideString propname = CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());\
408 CJS_PropValue PropValue(CJS_Value(isolate,value,VT_unknown));\
409 PropValue.StartSetting();\
410 CJS_Object* pJSObj = (CJS_Object*)JS_GetPrivate(isolate,info.Holder());\
412 class_alternate* pObj = (class_alternate*)pJSObj->GetEmbedObject();\
413 ASSERT(pObj != NULL);\
414 JS_ErrorString sError;\
415 FX_BOOL bRet = FALSE;\
417 bRet = pObj->DoProperty(cc, (FX_LPCWSTR)propname, PropValue, sError);\
418 MEMLEAKCHECK_2(class_name,L"PutProperty");\
425 CFX_ByteString cbName;\
426 cbName.Format("%s.%s", #class_name, "PutProperty");\
427 JS_Error(NULL,CFX_WideString::FromLocal(cbName), sError);\
430 JS_Error(NULL,L"PutProperty", L"Embeded object not found!");\
433 void js_class_name::delprop_##js_class_name##_static(JS_PROPDEL_ARGS)\
435 v8::Isolate* isolate = info.GetIsolate();\
436 v8::Local<v8::Context> context = isolate->GetCurrentContext();\
437 v8::Local<v8::Value> v = context->GetEmbedderData(1);\
438 ASSERT(!v.IsEmpty());\
439 if(v.IsEmpty()) return;\
440 v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(v);\
441 IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)field->Value();\
442 IFXJS_Context* cc = pRuntime->GetCurrentContext();\
443 v8::String::Utf8Value utf8_value(property);\
444 CFX_WideString propname = CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());\
445 CJS_Object* pJSObj = (CJS_Object*)JS_GetPrivate(isolate,info.Holder());\
446 ASSERT(pJSObj != NULL);\
447 class_alternate* pObj = (class_alternate*)pJSObj->GetEmbedObject();\
448 ASSERT(pObj != NULL);\
449 JS_ErrorString sError;\
450 FX_BOOL bRet = FALSE;\
452 bRet = pObj->DelProperty(cc, (FX_LPCWSTR)propname, sError);\
453 MEMLEAKCHECK_2(class_name,L"DelProperty");\
460 CFX_ByteString cbName;\
461 cbName.Format("%s.%s", #class_name, "DelProperty");\
466 JSBool js_class_name::JSConstructor(IFXJS_Context* cc, JSFXObject obj,JSFXObject global)\
468 CJS_Object* pObj = FX_NEW js_class_name(obj);\
469 pObj->SetEmbedObject(FX_NEW class_alternate(pObj));\
470 JS_SetPrivate(NULL,obj, (void*)pObj); \
471 pObj->InitInstance(cc);\
475 JSBool js_class_name::JSDestructor(JSFXObject obj) \
477 js_class_name* pObj = (js_class_name*)JS_GetPrivate(NULL,obj);\
478 ASSERT(pObj != NULL);\
479 pObj->ExitInstance();\
484 int js_class_name::Init(IJS_Runtime* pRuntime, FXJSOBJTYPE eObjType)\
487 int nObjDefnID = JS_DefineObj(pRuntime, js_class_name::m_pClassName, eObjType, JSConstructor, JSDestructor, 0);\
489 if (nObjDefnID >= 0)\
491 for (int j=0, szj=sizeof(JS_Class_Properties)/sizeof(JSPropertySpec)-1; j<szj; j++)\
493 if (JS_DefineObjProperty(pRuntime, nObjDefnID, JS_Class_Properties[j].pName, JS_Class_Properties[j].pPropGet,JS_Class_Properties[j].pPropPut)<0)return -1;\
496 for (int k=0, szk=sizeof(JS_Class_Methods)/sizeof(JSMethodSpec)-1; k<szk; k++)\
498 if (JS_DefineObjMethod(pRuntime, nObjDefnID,JS_Class_Methods[k].pName,JS_Class_Methods[k].pMethodCall,JS_Class_Methods[k].nParamNum)<0)return -1;\
500 if (JS_DefineObjAllProperties(pRuntime, nObjDefnID, js_class_name::queryprop_##js_class_name##_static, js_class_name::getprop_##js_class_name##_static,js_class_name::putprop_##js_class_name##_static,js_class_name::delprop_##js_class_name##_static)<0) return -1;\
507 void js_class_name::GetConsts(JSConstSpec*& pConsts, int& nSize)\
509 pConsts = JS_Class_Consts;\
510 nSize = sizeof(JS_Class_Consts)/sizeof(JSConstSpec)-1;\
512 void js_class_name::GetProperties(JSPropertySpec*& pProperties, int& nSize)\
514 pProperties = JS_Class_Properties;\
515 nSize = sizeof(JS_Class_Properties)/sizeof(JSPropertySpec)-1;\
517 void js_class_name::GetMethods(JSMethodSpec*& pMethods, int& nSize)\
519 pMethods = JS_Class_Methods;\
520 nSize = sizeof(JS_Class_Methods)/sizeof(JSMethodSpec)-1;\
523 #define JS_SPECIAL_STATIC_METHOD(method_name, class_alternate, class_name)\
524 static void method_name##_static(JS_METHOD_ARGS)\
526 v8::Isolate* isolate = info.GetIsolate();\
527 v8::Local<v8::Context> context = isolate->GetCurrentContext();\
528 v8::Local<v8::Value> v = context->GetEmbedderData(1);\
529 ASSERT(!v.IsEmpty());\
530 if(v.IsEmpty()) return;\
531 v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(v);\
532 IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)field->Value();\
533 IFXJS_Context* cc = pRuntime->GetCurrentContext();\
534 CJS_Parameters parameters;\
535 for (unsigned int i = 0; i<(unsigned int)info.Length(); i++)\
537 parameters.push_back(CJS_Value(isolate, info[i], VT_unknown));\
539 CJS_Value valueRes(isolate);\
540 CJS_Object* pJSObj = (CJS_Object *)JS_GetPrivate(isolate, info.Holder());\
541 ASSERT(pJSObj != NULL);\
542 class_alternate* pObj = (class_alternate*)pJSObj->GetEmbedObject();\
543 ASSERT(pObj != NULL);\
544 JS_ErrorString sError;\
545 FX_BOOL bRet = FALSE;\
547 bRet = pObj->method_name(cc, parameters, valueRes, sError);\
548 MEMLEAKCHECK_2(class_name, method_name);\
551 info.GetReturnValue().Set(valueRes.ToJSValue());\
556 CFX_ByteString cbName;\
557 cbName.Format("%s.%s", #class_name, #method_name);\
558 JS_Error(NULL, CFX_WideString::FromLocal(cbName), sError);\
561 JS_Error(NULL, JS_WIDESTRING(method_name), L"Embeded object not found!");\
565 /* ======================================== GLOBAL METHODS ============================================ */
566 #define JS_STATIC_GLOBAL_FUN(fun_name) \
567 static void fun_name##_static(JS_METHOD_ARGS)\
569 v8::Isolate* isolate = info.GetIsolate();\
570 v8::Local<v8::Context> context = isolate->GetCurrentContext();\
571 v8::Local<v8::Value> v = context->GetEmbedderData(1);\
572 ASSERT(!v.IsEmpty());\
573 if(v.IsEmpty()) return;\
574 v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(v);\
575 IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)field->Value();\
576 IFXJS_Context* cc = pRuntime->GetCurrentContext();\
577 CJS_Parameters parameters;\
578 for (unsigned int i = 0; i<(unsigned int)info.Length(); i++)\
580 parameters.push_back(CJS_Value(isolate, info[i], VT_unknown));\
582 CJS_Value valueRes(isolate);\
583 JS_ErrorString sError;\
584 if (!fun_name(cc, parameters, valueRes, sError))\
586 JS_Error(NULL, JS_WIDESTRING(fun_name), sError);\
589 info.GetReturnValue().Set(valueRes.ToJSValue());\
593 #define JS_STATIC_DECLARE_GLOBAL_FUN() \
594 static JSMethodSpec global_methods[]; \
595 static int Init(IJS_Runtime* pRuntime)
597 #define BEGIN_JS_STATIC_GLOBAL_FUN(js_class_name) \
598 JSMethodSpec js_class_name::global_methods[] = {
600 #define JS_STATIC_GLOBAL_FUN_ENTRY(method_name,nargs) JS_STATIC_METHOD_ENTRY(method_name,nargs)
602 #define END_JS_STATIC_GLOBAL_FUN() END_JS_STATIC_METHOD()
604 #define IMPLEMENT_JS_STATIC_GLOBAL_FUN(js_class_name) \
605 int js_class_name::Init(IJS_Runtime* pRuntime)\
607 for (int i=0, sz=sizeof(js_class_name::global_methods)/sizeof(JSMethodSpec)-1; i<sz; i++)\
609 if (JS_DefineGlobalMethod(pRuntime,\
610 js_class_name::global_methods[i].pName,\
611 js_class_name::global_methods[i].pMethodCall,\
612 js_class_name::global_methods[i].nParamNum\
619 /* ======================================== GLOBAL CONSTS ============================================ */
620 #define DEFINE_GLOBAL_CONST(pRuntime, const_name , const_value)\
621 if (JS_DefineGlobalConst(pRuntime,JS_WIDESTRING(const_name),JS_NewString(pRuntime,JS_WIDESTRING(const_value)))) return -1
623 /* ======================================== GLOBAL ARRAYS ============================================ */
625 #define DEFINE_GLOBAL_ARRAY(pRuntime)\
626 int size = sizeof(ArrayContent) / sizeof(FX_LPCWSTR);\
628 CJS_Array array(pRuntime);\
629 for (int i=0; i<size; i++) array.SetElement(i,CJS_Value(pRuntime,(FX_LPCWSTR)ArrayContent[i]));\
631 CJS_PropValue prop(pRuntime);\
633 if (JS_DefineGlobalConst(pRuntime, (const wchar_t*)ArrayName, prop.ToJSValue()) < 0)\
636 /* ============================================================ */
638 #define VALUE_NAME_STRING L"string"
639 #define VALUE_NAME_NUMBER L"number"
640 #define VALUE_NAME_BOOLEAN L"boolean"
641 #define VALUE_NAME_DATE L"date"
642 #define VALUE_NAME_OBJECT L"object"
643 #define VALUE_NAME_FXOBJ L"fxobj"
644 #define VALUE_NAME_NULL L"null"
645 #define VALUE_NAME_UNDEFINED L"undefined"
647 #define CLASSNAME_ARRAY L"Array"
648 #define CLASSNAME_DATE L"Date"
649 #define CLASSNAME_STRING L"v8::String"
651 const unsigned int JSCONST_nStringHash = JS_CalcHash(VALUE_NAME_STRING,wcslen(VALUE_NAME_STRING));
652 const unsigned int JSCONST_nNumberHash = JS_CalcHash(VALUE_NAME_NUMBER,wcslen(VALUE_NAME_NUMBER));
653 const unsigned int JSCONST_nBoolHash = JS_CalcHash(VALUE_NAME_BOOLEAN,wcslen(VALUE_NAME_BOOLEAN));
654 const unsigned int JSCONST_nDateHash = JS_CalcHash(VALUE_NAME_DATE,wcslen(VALUE_NAME_DATE));
655 const unsigned int JSCONST_nObjectHash = JS_CalcHash(VALUE_NAME_OBJECT,wcslen(VALUE_NAME_OBJECT));
656 const unsigned int JSCONST_nFXobjHash = JS_CalcHash(VALUE_NAME_FXOBJ,wcslen(VALUE_NAME_FXOBJ));
657 const unsigned int JSCONST_nNullHash = JS_CalcHash(VALUE_NAME_NULL,wcslen(VALUE_NAME_NULL));
658 const unsigned int JSCONST_nUndefHash = JS_CalcHash(VALUE_NAME_UNDEFINED,wcslen(VALUE_NAME_UNDEFINED));
660 static FXJSVALUETYPE GET_VALUE_TYPE(v8::Handle<v8::Value> p)
663 const unsigned int nHash = JS_CalcHash(JS_GetTypeof(p));
665 if (nHash == JSCONST_nUndefHash)
667 else if (nHash == JSCONST_nNullHash)
669 else if (nHash == JSCONST_nStringHash)
671 else if (nHash == JSCONST_nNumberHash)
673 else if (nHash == JSCONST_nBoolHash)
675 else if (nHash == JSCONST_nDateHash)
677 else if (nHash == JSCONST_nObjectHash)
679 else if (nHash == JSCONST_nFXobjHash)
683 const char * sType = p->getTypeof()->toDchars();
684 if (strcmp(sType,VALUE_NAME_STRING) == 0)
686 else if (strcmp(sType,VALUE_NAME_NUMBER) == 0)
688 else if (strcmp(sType,VALUE_NAME_BOOLEAN) == 0)
690 else if (strcmp(sType,VALUE_NAME_DATE) == 0)
692 else if (strcmp(sType,VALUE_NAME_OBJECT) == 0)
694 else if (strcmp(sType,VALUE_NAME_FXOBJ) == 0)
696 else if (strcmp(sType,VALUE_NAME_NULL) == 0)
698 else if (strcmp(sType,VALUE_NAME_UNDEFINED) == 0)
705 #endif //_JS_DEFINE_H_