1 // Copyright 2014 PDFium Authors. All rights reserved.
\r
2 // Use of this source code is governed by a BSD-style license that can be
\r
3 // found in the LICENSE file.
\r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
\r
7 #ifndef _JS_DEFINE_H_
\r
8 #define _JS_DEFINE_H_
\r
10 typedef v8::Value JSValue;
\r
11 typedef v8::Handle<v8::Object> JSObject;
\r
12 typedef v8::Handle<v8::Object> JSFXObject;
\r
13 typedef unsigned JSBool;
\r
17 const wchar_t* pName;
\r
19 const wchar_t* string;
\r
20 FX_BYTE t; //0:double 1:str
\r
23 struct JSPropertySpec
\r
25 const wchar_t* pName;
\r
26 v8::AccessorGetterCallback pPropGet;
\r
27 v8::AccessorSetterCallback pPropPut;
\r
32 const wchar_t* pName;
\r
33 v8::FunctionCallback pMethodCall;
\r
37 typedef CFX_WideString JS_ErrorString;
\r
39 #define JS_TRUE (unsigned)1
\r
40 #define JS_FALSE (unsigned)0
\r
43 #define CJS_PointsArray CFX_ArrayTemplate<float>
\r
44 #define CJS_IntArray CFX_ArrayTemplate<int>
\r
46 /* ====================================== PUBLIC DEFINE SPEC ============================================== */
\r
48 #define JS_WIDESTRING(widestring) L#widestring
\r
50 #define JS_WIDESTRING(widestring) L""#widestring
\r
53 #define OBJ_PROP_PARAMS IFXJS_Context* cc, CJS_PropValue& vp, JS_ErrorString& sError
\r
54 #define OBJ_METHOD_PARAMS IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, JS_ErrorString& sError
\r
55 #define BEGIN_JS_STATIC_CONST(js_class_name) JSConstSpec js_class_name::JS_Class_Consts[] = {
\r
56 #define JS_STATIC_CONST_ENTRY_NUMBER(const_name, pValue) {JS_WIDESTRING(const_name), pValue, L"", 0},
\r
57 #define JS_STATIC_CONST_ENTRY_STRING(const_name, pValue) {JS_WIDESTRING(const_name), 0, JS_WIDESTRING(pValue), 1},
\r
58 #define END_JS_STATIC_CONST() {0, 0, 0, 0}};
\r
60 #define BEGIN_JS_STATIC_PROP(js_class_name) JSPropertySpec js_class_name::JS_Class_Properties[] = {
\r
61 #define JS_STATIC_PROP_ENTRY(prop_name) {JS_WIDESTRING(prop_name), get_##prop_name##_static, set_##prop_name##_static},
\r
62 #define END_JS_STATIC_PROP() {0, 0, 0}};
\r
64 #define BEGIN_JS_STATIC_METHOD(js_class_name) JSMethodSpec js_class_name::JS_Class_Methods[] = {
\r
65 #define JS_STATIC_METHOD_ENTRY(method_name, nargs) {JS_WIDESTRING(method_name), method_name##_static, nargs},
\r
66 #define END_JS_STATIC_METHOD() {0, 0, 0}};
\r
67 #define MEMLEAKCHECK_1() ((void)0)
\r
68 #define MEMLEAKCHECK_2(main_name, sub_name) ((void)0)
\r
73 #define MEMLEAKCHECK_1() \
\r
74 _CrtMemState state1;\
\r
75 _CrtMemCheckpoint(&state1);
\r
77 #define MEMLEAKCHECK_2(main_name,sub_name) \
\r
78 _CrtMemState state2;\
\r
79 _CrtMemCheckpoint(&state2);\
\r
81 _CrtMemDifference(&diff,&state1,&state2);\
\r
82 if (diff.lSizes[_NORMAL_BLOCK] > 0)\
\r
84 TRACE("Detected normal block memory leaks in JS Module! [%s.%s]\n",#main_name,#sub_name);\
\r
85 _CrtMemDumpStatistics(&diff);\
\r
88 #define MEMLEAKCHECK_1() ((void)0)
\r
89 #define MEMLEAKCHECK_2(main_name,sub_name) ((void)0)
\r
93 /* ======================================== PROP CALLBACK ============================================ */
\r
95 #define JS_STATIC_PROP_GET(prop_name, class_name)\
\r
96 static void get_##prop_name##_static(JS_PROPGET_ARGS)\
\r
98 v8::Isolate* isolate = info.GetIsolate();\
\r
99 v8::Local<v8::Context> context = isolate->GetCurrentContext();\
\r
100 v8::Local<v8::Value> v = context->GetEmbedderData(1);\
\r
101 ASSERT(!v.IsEmpty());\
\r
102 if(v.IsEmpty()) return;\
\r
103 v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(v);\
\r
104 IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)field->Value();\
\r
105 IFXJS_Context* cc = pRuntime->GetCurrentContext();\
\r
106 CJS_PropValue value(isolate);\
\r
107 value.StartGetting();\
\r
108 CJS_Object* pJSObj = (CJS_Object*)JS_GetPrivate(isolate,info.Holder());\
\r
109 ASSERT(pJSObj != NULL);\
\r
110 class_name* pObj = (class_name*)pJSObj->GetEmbedObject();\
\r
111 ASSERT(pObj != NULL);\
\r
112 JS_ErrorString sError;\
\r
113 FX_BOOL bRet = FALSE;\
\r
117 bRet = pObj->prop_name(cc, value, sError);\
\r
118 MEMLEAKCHECK_2(class_name, prop_name);\
\r
122 CFX_ByteString cbName;\
\r
123 cbName.Format("%s.%s", #class_name, #prop_name);\
\r
124 JS_Error(NULL,CFX_WideString::FromLocal(cbName), L"Unknown error is catched!");\
\r
129 info.GetReturnValue().Set((v8::Handle<v8::Value>)value);\
\r
134 CFX_ByteString cbName;\
\r
135 cbName.Format("%s.%s", #class_name, #prop_name);\
\r
136 JS_Error(NULL,CFX_WideString::FromLocal(cbName), sError);\
\r
141 #define JS_STATIC_PROP_SET(prop_name, class_name)\
\r
142 static void set_##prop_name##_static(JS_PROPPUT_ARGS)\
\r
144 v8::Isolate* isolate = info.GetIsolate();\
\r
145 v8::Local<v8::Context> context = isolate->GetCurrentContext();\
\r
146 v8::Local<v8::Value> v = context->GetEmbedderData(1);\
\r
147 ASSERT(!v.IsEmpty());\
\r
148 if(v.IsEmpty()) return;\
\r
149 v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(v);\
\r
150 IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)field->Value();\
\r
151 IFXJS_Context* cc = pRuntime->GetCurrentContext();\
\r
152 CJS_PropValue propValue(CJS_Value(isolate,value,VT_unknown));\
\r
153 propValue.StartSetting();\
\r
154 CJS_Object* pJSObj = (CJS_Object*)JS_GetPrivate(isolate,info.Holder());\
\r
155 ASSERT(pJSObj != NULL);\
\r
156 class_name* pObj = (class_name*)pJSObj->GetEmbedObject();\
\r
157 ASSERT(pObj != NULL);\
\r
158 JS_ErrorString sError;\
\r
159 FX_BOOL bRet = FALSE;\
\r
163 bRet = pObj->prop_name(cc, propValue, sError);\
\r
164 MEMLEAKCHECK_2(class_name, prop_name);\
\r
168 CFX_ByteString cbName;\
\r
169 cbName.Format("%s.%s", #class_name, #prop_name);\
\r
170 JS_Error(NULL,CFX_WideString::FromLocal(cbName), L"Unknown error is catched!");\
\r
179 CFX_ByteString cbName;\
\r
180 cbName.Format("%s.%s", #class_name, #prop_name);\
\r
181 JS_Error(NULL,CFX_WideString::FromLocal(cbName), sError);\
\r
186 #define JS_STATIC_PROP(prop_name, class_name)\
\r
187 JS_STATIC_PROP_GET(prop_name, class_name);\
\r
188 JS_STATIC_PROP_SET(prop_name, class_name)
\r
190 /* ========================================= METHOD CALLBACK =========================================== */
\r
192 #define JS_STATIC_METHOD(method_name, class_name)\
\r
193 static void method_name##_static(JS_METHOD_ARGS)\
\r
195 v8::Isolate* isolate = info.GetIsolate();\
\r
196 v8::Local<v8::Context> context = isolate->GetCurrentContext();\
\r
197 v8::Local<v8::Value> v = context->GetEmbedderData(1);\
\r
198 ASSERT(!v.IsEmpty());\
\r
199 if(v.IsEmpty()) return;\
\r
200 v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(v);\
\r
201 IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)field->Value();\
\r
202 IFXJS_Context* cc = pRuntime->GetCurrentContext();\
\r
203 CJS_Parameters parameters;\
\r
204 for (unsigned int i = 0; i<(unsigned int)info.Length(); i++)\
\r
206 parameters.push_back(CJS_Value(isolate, info[i], VT_unknown));\
\r
208 CJS_Value valueRes(isolate);\
\r
209 CJS_Object* pJSObj = (CJS_Object *)JS_GetPrivate(isolate,info.Holder());\
\r
210 ASSERT(pJSObj != NULL);\
\r
211 class_name* pObj = (class_name*)pJSObj->GetEmbedObject();\
\r
212 ASSERT(pObj != NULL);\
\r
213 JS_ErrorString sError;\
\r
214 FX_BOOL bRet = FALSE;\
\r
218 bRet = pObj->method_name(cc, parameters, valueRes, sError);\
\r
219 MEMLEAKCHECK_2(class_name, method_name);\
\r
223 CFX_ByteString cbName;\
\r
224 cbName.Format("%s.%s", #class_name, #method_name);\
\r
225 JS_Error(NULL, CFX_WideString::FromLocal(cbName), L"Unknown error is catched!");\
\r
230 info.GetReturnValue().Set(valueRes.ToJSValue());\
\r
235 CFX_ByteString cbName;\
\r
236 cbName.Format("%s.%s", #class_name, #method_name);\
\r
237 JS_Error(NULL, CFX_WideString::FromLocal(cbName), sError);\
\r
242 /* ===================================== JS CLASS =============================================== */
\r
244 #define DECLARE_JS_CLASS(js_class_name) \
\r
245 static JSBool JSConstructor(IFXJS_Context* cc, JSFXObject obj,JSFXObject global);\
\r
246 static JSBool JSDestructor(JSFXObject obj);\
\r
247 static int Init(IJS_Runtime* pRuntime, FXJSOBJTYPE eObjType);\
\r
248 static void GetConsts(JSConstSpec*& pConsts, int& nSize);\
\r
249 static void GetProperties(JSPropertySpec*& pProperties, int& nSize);\
\r
250 static void GetMethods(JSMethodSpec*& pMethods, int& nSize);\
\r
251 static JSConstSpec JS_Class_Consts[];\
\r
252 static JSPropertySpec JS_Class_Properties[];\
\r
253 static JSMethodSpec JS_Class_Methods[];\
\r
254 static const wchar_t* m_pClassName
\r
256 #define IMPLEMENT_JS_CLASS_RICH(js_class_name, class_alternate, class_name) \
\r
257 const wchar_t* js_class_name::m_pClassName = JS_WIDESTRING(class_name);\
\r
258 JSBool js_class_name::JSConstructor(IFXJS_Context* cc, JSFXObject obj, JSFXObject global)\
\r
260 CJS_Object* pObj = FX_NEW js_class_name(obj);\
\r
261 pObj->SetEmbedObject(FX_NEW class_alternate(pObj));\
\r
262 JS_SetPrivate(NULL,obj,(void*)pObj); \
\r
263 pObj->InitInstance(cc);\
\r
267 JSBool js_class_name::JSDestructor(JSFXObject obj) \
\r
269 js_class_name* pObj = (js_class_name*)JS_GetPrivate(NULL,obj);\
\r
270 ASSERT(pObj != NULL);\
\r
271 pObj->ExitInstance();\
\r
276 int js_class_name::Init(IJS_Runtime* pRuntime, FXJSOBJTYPE eObjType)\
\r
278 int nObjDefnID = JS_DefineObj(pRuntime, js_class_name::m_pClassName, eObjType, JSConstructor, JSDestructor, 0);\
\r
279 if (nObjDefnID >= 0)\
\r
281 for (int j=0, szj=sizeof(JS_Class_Properties)/sizeof(JSPropertySpec)-1; j<szj; j++)\
\r
283 if (JS_DefineObjProperty(pRuntime, nObjDefnID, JS_Class_Properties[j].pName, JS_Class_Properties[j].pPropGet, JS_Class_Properties[j].pPropPut) < 0) return -1;\
\r
285 for (int k=0, szk=sizeof(JS_Class_Methods)/sizeof(JSMethodSpec)-1; k<szk; k++)\
\r
287 if (JS_DefineObjMethod(pRuntime, nObjDefnID,JS_Class_Methods[k].pName, JS_Class_Methods[k].pMethodCall, JS_Class_Methods[k].nParamNum) < 0) return -1;\
\r
289 return nObjDefnID;\
\r
293 void js_class_name::GetConsts(JSConstSpec*& pConsts, int& nSize)\
\r
295 pConsts = JS_Class_Consts;\
\r
296 nSize = sizeof(JS_Class_Consts) / sizeof(JSConstSpec) - 1;\
\r
298 void js_class_name::GetProperties(JSPropertySpec*& pProperties, int& nSize)\
\r
300 pProperties = JS_Class_Properties;\
\r
301 nSize = sizeof(JS_Class_Properties) / sizeof(JSPropertySpec) - 1;\
\r
303 void js_class_name::GetMethods(JSMethodSpec*& pMethods, int& nSize)\
\r
305 pMethods = JS_Class_Methods;\
\r
306 nSize = sizeof(JS_Class_Methods) / sizeof(JSMethodSpec) - 1;\
\r
309 #define IMPLEMENT_JS_CLASS(js_class_name, class_name) IMPLEMENT_JS_CLASS_RICH(js_class_name, class_name, class_name)
\r
311 /* ======================================== CONST CLASS ============================================ */
\r
313 #define DECLARE_JS_CLASS_CONST() \
\r
314 static int Init(IJS_Runtime* pRuntime, FXJSOBJTYPE eObjType);\
\r
315 static void GetConsts(JSConstSpec*& pConsts, int& nSize);\
\r
316 static JSConstSpec JS_Class_Consts[];\
\r
317 static const wchar_t* m_pClassName
\r
319 #define IMPLEMENT_JS_CLASS_CONST(js_class_name, class_name) \
\r
320 const wchar_t* js_class_name::m_pClassName = JS_WIDESTRING(class_name);\
\r
321 int js_class_name::Init(IJS_Runtime* pRuntime, FXJSOBJTYPE eObjType)\
\r
323 int nObjDefnID = JS_DefineObj(pRuntime, js_class_name::m_pClassName, eObjType, NULL, NULL, 0);\
\r
324 if (nObjDefnID >=0)\
\r
326 for (int i=0, sz=sizeof(JS_Class_Consts)/sizeof(JSConstSpec)-1; i<sz; i++)\
\r
328 if (JS_Class_Consts[i].t == 0)\
\r
330 if (JS_DefineObjConst(pRuntime, nObjDefnID, JS_Class_Consts[i].pName, JS_NewNumber(pRuntime,JS_Class_Consts[i].number)) < 0) return -1;\
\r
334 if (JS_DefineObjConst(pRuntime, nObjDefnID, JS_Class_Consts[i].pName, JS_NewString(pRuntime,JS_Class_Consts[i].string)) < 0) return -1;\
\r
337 return nObjDefnID;\
\r
341 void js_class_name::GetConsts(JSConstSpec*& pConsts, int& nSize)\
\r
343 pConsts = JS_Class_Consts;\
\r
344 nSize = sizeof(JS_Class_Consts)/sizeof(JSConstSpec)-1;\
\r
347 /* ===================================== SPECIAL JS CLASS =============================================== */
\r
349 #define DECLARE_SPECIAL_JS_CLASS(js_class_name) \
\r
350 static JSBool JSConstructor(IFXJS_Context* cc, JSFXObject obj, JSFXObject global);\
\r
351 static JSBool JSDestructor(JSFXObject obj);\
\r
352 static void GetConsts(JSConstSpec*& pConsts, int& nSize);\
\r
353 static void GetProperties(JSPropertySpec*& pProperties, int& nSize);\
\r
354 static void GetMethods(JSMethodSpec*& pMethods, int& nSize);\
\r
355 static JSConstSpec JS_Class_Consts[];\
\r
356 static JSPropertySpec JS_Class_Properties[];\
\r
357 static JSMethodSpec JS_Class_Methods[];\
\r
358 static int Init(IJS_Runtime* pRuntime, FXJSOBJTYPE eObjType);\
\r
359 static const wchar_t* m_pClassName;\
\r
360 static void queryprop_##js_class_name##_static(JS_PROPQUERY_ARGS);\
\r
361 static void getprop_##js_class_name##_static(JS_NAMED_PROPGET_ARGS);\
\r
362 static void putprop_##js_class_name##_static(JS_NAMED_PROPPUT_ARGS);\
\r
363 static void delprop_##js_class_name##_static(JS_PROPDEL_ARGS)
\r
365 #define IMPLEMENT_SPECIAL_JS_CLASS(js_class_name, class_alternate, class_name) \
\r
366 const wchar_t * js_class_name::m_pClassName = JS_WIDESTRING(class_name);\
\r
367 void js_class_name::queryprop_##js_class_name##_static(JS_PROPQUERY_ARGS)\
\r
369 v8::Isolate* isolate = info.GetIsolate();\
\r
370 v8::String::Utf8Value utf8_value(property);\
\r
371 CFX_WideString propname = CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());\
\r
372 CJS_Object* pJSObj = (CJS_Object*)JS_GetPrivate(isolate,info.Holder());\
\r
373 ASSERT(pJSObj != NULL);\
\r
374 class_alternate* pObj = (class_alternate*)pJSObj->GetEmbedObject();\
\r
375 ASSERT(pObj != NULL);\
\r
376 FX_BOOL bRet = FALSE;\
\r
380 bRet = pObj->QueryProperty((FX_LPCWSTR)propname);\
\r
381 MEMLEAKCHECK_2(class_name, (FX_LPCWSTR)prop_name);\
\r
389 info.GetReturnValue().Set(0x004);\
\r
394 info.GetReturnValue().Set(0);\
\r
399 void js_class_name::getprop_##js_class_name##_static(JS_NAMED_PROPGET_ARGS)\
\r
401 v8::Isolate* isolate = info.GetIsolate();\
\r
402 v8::Local<v8::Context> context = isolate->GetCurrentContext();\
\r
403 v8::Local<v8::Value> v = context->GetEmbedderData(1);\
\r
404 ASSERT(!v.IsEmpty());\
\r
405 if(v.IsEmpty()) return;\
\r
406 v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(v);\
\r
407 IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)field->Value();\
\r
408 IFXJS_Context* cc = pRuntime->GetCurrentContext();\
\r
409 v8::String::Utf8Value utf8_value(property);\
\r
410 CFX_WideString propname = CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());\
\r
411 CJS_PropValue value(isolate);\
\r
412 value.StartGetting();\
\r
413 CJS_Object* pJSObj = (CJS_Object*)JS_GetPrivate(isolate,info.Holder());\
\r
414 ASSERT(pJSObj != NULL);\
\r
415 class_alternate* pObj = (class_alternate*)pJSObj->GetEmbedObject();\
\r
416 ASSERT(pObj != NULL);\
\r
417 JS_ErrorString sError;\
\r
418 FX_BOOL bRet = FALSE;\
\r
422 bRet = pObj->DoProperty(cc, (FX_LPCWSTR)propname, value, sError);\
\r
423 MEMLEAKCHECK_2(class_name, L"GetProperty");\
\r
427 CFX_ByteString cbName;\
\r
428 cbName.Format("%s.%s", #class_name, L"GetProperty");\
\r
429 JS_Error(NULL,CFX_WideString::FromLocal(cbName), L"Unknown error is catched!");\
\r
434 info.GetReturnValue().Set((v8::Handle<v8::Value>)value);\
\r
439 CFX_ByteString cbName;\
\r
440 cbName.Format("%s.%s", #class_name, L"GetProperty");\
\r
441 JS_Error(NULL,CFX_WideString::FromLocal(cbName), sError);\
\r
444 JS_Error(NULL,L"GetProperty", L"Embeded object not found!");\
\r
447 void js_class_name::putprop_##js_class_name##_static(JS_NAMED_PROPPUT_ARGS)\
\r
449 v8::Isolate* isolate = info.GetIsolate();\
\r
450 v8::Local<v8::Context> context = isolate->GetCurrentContext();\
\r
451 v8::Local<v8::Value> v = context->GetEmbedderData(1);\
\r
452 ASSERT(!v.IsEmpty());\
\r
453 if(v.IsEmpty()) return;\
\r
454 v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(v);\
\r
455 IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)field->Value();\
\r
456 IFXJS_Context* cc = pRuntime->GetCurrentContext();\
\r
457 v8::String::Utf8Value utf8_value(property);\
\r
458 CFX_WideString propname = CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());\
\r
459 CJS_PropValue PropValue(CJS_Value(isolate,value,VT_unknown));\
\r
460 PropValue.StartSetting();\
\r
461 CJS_Object* pJSObj = (CJS_Object*)JS_GetPrivate(isolate,info.Holder());\
\r
462 if(!pJSObj) return;\
\r
463 class_alternate* pObj = (class_alternate*)pJSObj->GetEmbedObject();\
\r
464 ASSERT(pObj != NULL);\
\r
465 JS_ErrorString sError;\
\r
466 FX_BOOL bRet = FALSE;\
\r
470 bRet = pObj->DoProperty(cc, (FX_LPCWSTR)propname, PropValue, sError);\
\r
471 MEMLEAKCHECK_2(class_name,L"PutProperty");\
\r
475 CFX_ByteString cbName;\
\r
476 cbName.Format("%s.%s", #class_name, "PutProperty");\
\r
477 JS_Error(NULL,CFX_WideString::FromLocal(cbName), L"Unknown error is catched!");\
\r
486 CFX_ByteString cbName;\
\r
487 cbName.Format("%s.%s", #class_name, "PutProperty");\
\r
488 JS_Error(NULL,CFX_WideString::FromLocal(cbName), sError);\
\r
491 JS_Error(NULL,L"PutProperty", L"Embeded object not found!");\
\r
494 void js_class_name::delprop_##js_class_name##_static(JS_PROPDEL_ARGS)\
\r
496 v8::Isolate* isolate = info.GetIsolate();\
\r
497 v8::Local<v8::Context> context = isolate->GetCurrentContext();\
\r
498 v8::Local<v8::Value> v = context->GetEmbedderData(1);\
\r
499 ASSERT(!v.IsEmpty());\
\r
500 if(v.IsEmpty()) return;\
\r
501 v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(v);\
\r
502 IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)field->Value();\
\r
503 IFXJS_Context* cc = pRuntime->GetCurrentContext();\
\r
504 v8::String::Utf8Value utf8_value(property);\
\r
505 CFX_WideString propname = CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());\
\r
506 CJS_Object* pJSObj = (CJS_Object*)JS_GetPrivate(isolate,info.Holder());\
\r
507 ASSERT(pJSObj != NULL);\
\r
508 class_alternate* pObj = (class_alternate*)pJSObj->GetEmbedObject();\
\r
509 ASSERT(pObj != NULL);\
\r
510 JS_ErrorString sError;\
\r
511 FX_BOOL bRet = FALSE;\
\r
515 bRet = pObj->DelProperty(cc, (FX_LPCWSTR)propname, sError);\
\r
516 MEMLEAKCHECK_2(class_name,L"DelProperty");\
\r
520 CFX_ByteString cbName;\
\r
521 cbName.Format("%s.%s", #class_name, "DelProperty");\
\r
530 CFX_ByteString cbName;\
\r
531 cbName.Format("%s.%s", #class_name, "DelProperty");\
\r
536 JSBool js_class_name::JSConstructor(IFXJS_Context* cc, JSFXObject obj,JSFXObject global)\
\r
538 CJS_Object* pObj = FX_NEW js_class_name(obj);\
\r
539 pObj->SetEmbedObject(FX_NEW class_alternate(pObj));\
\r
540 JS_SetPrivate(NULL,obj, (void*)pObj); \
\r
541 pObj->InitInstance(cc);\
\r
545 JSBool js_class_name::JSDestructor(JSFXObject obj) \
\r
547 js_class_name* pObj = (js_class_name*)JS_GetPrivate(NULL,obj);\
\r
548 ASSERT(pObj != NULL);\
\r
549 pObj->ExitInstance();\
\r
554 int js_class_name::Init(IJS_Runtime* pRuntime, FXJSOBJTYPE eObjType)\
\r
557 int nObjDefnID = JS_DefineObj(pRuntime, js_class_name::m_pClassName, eObjType, JSConstructor, JSDestructor, 0);\
\r
559 if (nObjDefnID >= 0)\
\r
561 for (int j=0, szj=sizeof(JS_Class_Properties)/sizeof(JSPropertySpec)-1; j<szj; j++)\
\r
563 if (JS_DefineObjProperty(pRuntime, nObjDefnID, JS_Class_Properties[j].pName, JS_Class_Properties[j].pPropGet,JS_Class_Properties[j].pPropPut)<0)return -1;\
\r
566 for (int k=0, szk=sizeof(JS_Class_Methods)/sizeof(JSMethodSpec)-1; k<szk; k++)\
\r
568 if (JS_DefineObjMethod(pRuntime, nObjDefnID,JS_Class_Methods[k].pName,JS_Class_Methods[k].pMethodCall,JS_Class_Methods[k].nParamNum)<0)return -1;\
\r
570 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;\
\r
572 return nObjDefnID;\
\r
577 void js_class_name::GetConsts(JSConstSpec*& pConsts, int& nSize)\
\r
579 pConsts = JS_Class_Consts;\
\r
580 nSize = sizeof(JS_Class_Consts)/sizeof(JSConstSpec)-1;\
\r
582 void js_class_name::GetProperties(JSPropertySpec*& pProperties, int& nSize)\
\r
584 pProperties = JS_Class_Properties;\
\r
585 nSize = sizeof(JS_Class_Properties)/sizeof(JSPropertySpec)-1;\
\r
587 void js_class_name::GetMethods(JSMethodSpec*& pMethods, int& nSize)\
\r
589 pMethods = JS_Class_Methods;\
\r
590 nSize = sizeof(JS_Class_Methods)/sizeof(JSMethodSpec)-1;\
\r
593 #define JS_SPECIAL_STATIC_METHOD(method_name, class_alternate, class_name)\
\r
594 static void method_name##_static(JS_METHOD_ARGS)\
\r
596 v8::Isolate* isolate = info.GetIsolate();\
\r
597 v8::Local<v8::Context> context = isolate->GetCurrentContext();\
\r
598 v8::Local<v8::Value> v = context->GetEmbedderData(1);\
\r
599 ASSERT(!v.IsEmpty());\
\r
600 if(v.IsEmpty()) return;\
\r
601 v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(v);\
\r
602 IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)field->Value();\
\r
603 IFXJS_Context* cc = pRuntime->GetCurrentContext();\
\r
604 CJS_Parameters parameters;\
\r
605 for (unsigned int i = 0; i<(unsigned int)info.Length(); i++)\
\r
607 parameters.push_back(CJS_Value(isolate, info[i], VT_unknown));\
\r
609 CJS_Value valueRes(isolate);\
\r
610 CJS_Object* pJSObj = (CJS_Object *)JS_GetPrivate(isolate, info.Holder());\
\r
611 ASSERT(pJSObj != NULL);\
\r
612 class_alternate* pObj = (class_alternate*)pJSObj->GetEmbedObject();\
\r
613 ASSERT(pObj != NULL);\
\r
614 JS_ErrorString sError;\
\r
615 FX_BOOL bRet = FALSE;\
\r
619 bRet = pObj->method_name(cc, parameters, valueRes, sError);\
\r
620 MEMLEAKCHECK_2(class_name, method_name);\
\r
624 CFX_ByteString cbName;\
\r
625 cbName.Format("%s.%s", #class_name, #method_name);\
\r
626 JS_Error(NULL, CFX_WideString::FromLocal(cbName), L"Unknown error is catched!");\
\r
631 info.GetReturnValue().Set(valueRes.ToJSValue());\
\r
636 CFX_ByteString cbName;\
\r
637 cbName.Format("%s.%s", #class_name, #method_name);\
\r
638 JS_Error(NULL, CFX_WideString::FromLocal(cbName), sError);\
\r
641 JS_Error(NULL, JS_WIDESTRING(method_name), L"Embeded object not found!");\
\r
645 /* ======================================== GLOBAL METHODS ============================================ */
\r
646 #define JS_STATIC_GLOBAL_FUN(fun_name) \
\r
647 static void fun_name##_static(JS_METHOD_ARGS)\
\r
649 v8::Isolate* isolate = info.GetIsolate();\
\r
650 v8::Local<v8::Context> context = isolate->GetCurrentContext();\
\r
651 v8::Local<v8::Value> v = context->GetEmbedderData(1);\
\r
652 ASSERT(!v.IsEmpty());\
\r
653 if(v.IsEmpty()) return;\
\r
654 v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(v);\
\r
655 IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)field->Value();\
\r
656 IFXJS_Context* cc = pRuntime->GetCurrentContext();\
\r
657 CJS_Parameters parameters;\
\r
658 for (unsigned int i = 0; i<(unsigned int)info.Length(); i++)\
\r
660 parameters.push_back(CJS_Value(isolate, info[i], VT_unknown));\
\r
662 CJS_Value valueRes(isolate);\
\r
663 JS_ErrorString sError;\
\r
664 if (!fun_name(cc, parameters, valueRes, sError))\
\r
666 JS_Error(NULL, JS_WIDESTRING(fun_name), sError);\
\r
669 info.GetReturnValue().Set(valueRes.ToJSValue());\
\r
673 #define JS_STATIC_DECLARE_GLOBAL_FUN() \
\r
674 static JSMethodSpec global_methods[]; \
\r
675 static int Init(IJS_Runtime* pRuntime)
\r
677 #define BEGIN_JS_STATIC_GLOBAL_FUN(js_class_name) \
\r
678 JSMethodSpec js_class_name::global_methods[] = {
\r
680 #define JS_STATIC_GLOBAL_FUN_ENTRY(method_name,nargs) JS_STATIC_METHOD_ENTRY(method_name,nargs)
\r
682 #define END_JS_STATIC_GLOBAL_FUN() END_JS_STATIC_METHOD()
\r
684 #define IMPLEMENT_JS_STATIC_GLOBAL_FUN(js_class_name) \
\r
685 int js_class_name::Init(IJS_Runtime* pRuntime)\
\r
687 for (int i=0, sz=sizeof(js_class_name::global_methods)/sizeof(JSMethodSpec)-1; i<sz; i++)\
\r
689 if (JS_DefineGlobalMethod(pRuntime,\
\r
690 js_class_name::global_methods[i].pName,\
\r
691 js_class_name::global_methods[i].pMethodCall,\
\r
692 js_class_name::global_methods[i].nParamNum\
\r
699 /* ======================================== GLOBAL CONSTS ============================================ */
\r
700 #define DEFINE_GLOBAL_CONST(pRuntime, const_name , const_value)\
\r
701 if (JS_DefineGlobalConst(pRuntime,JS_WIDESTRING(const_name),JS_NewString(pRuntime,JS_WIDESTRING(const_value)))) return -1
\r
703 /* ======================================== GLOBAL ARRAYS ============================================ */
\r
705 #define DEFINE_GLOBAL_ARRAY(pRuntime)\
\r
706 int size = sizeof(ArrayContent) / sizeof(FX_LPCWSTR);\
\r
708 CJS_Array array(pRuntime);\
\r
709 for (int i=0; i<size; i++) array.SetElement(i,CJS_Value(pRuntime,(FX_LPCWSTR)ArrayContent[i]));\
\r
711 CJS_PropValue prop(pRuntime);\
\r
713 if (JS_DefineGlobalConst(pRuntime, (const wchar_t*)ArrayName, prop.ToJSValue()) < 0)\
\r
716 /* ============================================================ */
\r
718 #define VALUE_NAME_STRING L"string"
\r
719 #define VALUE_NAME_NUMBER L"number"
\r
720 #define VALUE_NAME_BOOLEAN L"boolean"
\r
721 #define VALUE_NAME_DATE L"date"
\r
722 #define VALUE_NAME_OBJECT L"object"
\r
723 #define VALUE_NAME_FXOBJ L"fxobj"
\r
724 #define VALUE_NAME_NULL L"null"
\r
725 #define VALUE_NAME_UNDEFINED L"undefined"
\r
727 #define CLASSNAME_ARRAY L"Array"
\r
728 #define CLASSNAME_DATE L"Date"
\r
729 #define CLASSNAME_STRING L"v8::String"
\r
731 const unsigned int JSCONST_nStringHash = JS_CalcHash(VALUE_NAME_STRING,wcslen(VALUE_NAME_STRING));
\r
732 const unsigned int JSCONST_nNumberHash = JS_CalcHash(VALUE_NAME_NUMBER,wcslen(VALUE_NAME_NUMBER));
\r
733 const unsigned int JSCONST_nBoolHash = JS_CalcHash(VALUE_NAME_BOOLEAN,wcslen(VALUE_NAME_BOOLEAN));
\r
734 const unsigned int JSCONST_nDateHash = JS_CalcHash(VALUE_NAME_DATE,wcslen(VALUE_NAME_DATE));
\r
735 const unsigned int JSCONST_nObjectHash = JS_CalcHash(VALUE_NAME_OBJECT,wcslen(VALUE_NAME_OBJECT));
\r
736 const unsigned int JSCONST_nFXobjHash = JS_CalcHash(VALUE_NAME_FXOBJ,wcslen(VALUE_NAME_FXOBJ));
\r
737 const unsigned int JSCONST_nNullHash = JS_CalcHash(VALUE_NAME_NULL,wcslen(VALUE_NAME_NULL));
\r
738 const unsigned int JSCONST_nUndefHash = JS_CalcHash(VALUE_NAME_UNDEFINED,wcslen(VALUE_NAME_UNDEFINED));
\r
740 static FXJSVALUETYPE GET_VALUE_TYPE(v8::Handle<v8::Value> p)
\r
743 const unsigned int nHash = JS_CalcHash(JS_GetTypeof(p));
\r
745 if (nHash == JSCONST_nUndefHash)
\r
746 return VT_undefined;
\r
747 else if (nHash == JSCONST_nNullHash)
\r
749 else if (nHash == JSCONST_nStringHash)
\r
751 else if (nHash == JSCONST_nNumberHash)
\r
753 else if (nHash == JSCONST_nBoolHash)
\r
755 else if (nHash == JSCONST_nDateHash)
\r
757 else if (nHash == JSCONST_nObjectHash)
\r
759 else if (nHash == JSCONST_nFXobjHash)
\r
760 return VT_fxobject;
\r
763 const char * sType = p->getTypeof()->toDchars();
\r
764 if (strcmp(sType,VALUE_NAME_STRING) == 0)
\r
766 else if (strcmp(sType,VALUE_NAME_NUMBER) == 0)
\r
768 else if (strcmp(sType,VALUE_NAME_BOOLEAN) == 0)
\r
770 else if (strcmp(sType,VALUE_NAME_DATE) == 0)
\r
772 else if (strcmp(sType,VALUE_NAME_OBJECT) == 0)
\r
774 else if (strcmp(sType,VALUE_NAME_FXOBJ) == 0)
\r
776 else if (strcmp(sType,VALUE_NAME_NULL) == 0)
\r
778 else if (strcmp(sType,VALUE_NAME_UNDEFINED) == 0)
\r
779 return VT_undefined;
\r
785 #endif //_JS_DEFINE_H_
\r