#include "wsint.h"Include dependency graph for wsbc.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.
|
|
Definition at line 102 of file wsbc.h. Referenced by ws_bc_decode(), and ws_bc_encode(). |
|
|
Definition at line 103 of file wsbc.h. Referenced by ws_bc_decode(), and ws_bc_encode(). |
|
|
|
|
|
Definition at line 100 of file wsbc.h. Referenced by ws_bc_decode(), and ws_bc_encode(). |
|
|
Definition at line 98 of file wsbc.h. Referenced by ws_bc_decode(), and ws_bc_encode(). |
|
|
Definition at line 99 of file wsbc.h. Referenced by ws_bc_decode(), and ws_bc_encode(). |
|
|
Definition at line 97 of file wsbc.h. Referenced by ws_bc_decode(), and ws_bc_encode(). |
|
|
Definition at line 101 of file wsbc.h. Referenced by ws_bc_decode(), and ws_bc_encode(). |
|
|
Definition at line 84 of file wsbc.h. Referenced by ws_bc_encode(). |
|
|
Definition at line 134 of file wsbc.h. Referenced by ws_bc_decode(), and ws_bc_encode(). |
|
|
Definition at line 135 of file wsbc.h. Referenced by ws_bc_decode(), and ws_bc_encode(). |
|
|
|
|
|
Definition at line 136 of file wsbc.h. Referenced by ws_bc_decode(), and ws_bc_encode(). |
|
|
Definition at line 137 of file wsbc.h. Referenced by ws_bc_decode(), and ws_bc_encode(). |
|
|
Definition at line 80 of file wsbc.h. Referenced by ws_bc_decode(), and ws_bc_encode(). |
|
|
|
|
|
|
|
|
|
Definition at line 131 of file wsbc.h. Referenced by ws_bc_add_const_empty_string(), ws_bc_add_const_float(), ws_bc_add_const_int(), ws_bc_add_const_utf8_string(), ws_bc_decode(), and ws_bc_free(). |
|
|
Definition at line 183 of file wsbc.h. Referenced by ws_bc_add_function(), and ws_bc_decode(). |
|
|
Definition at line 172 of file wsbc.h. Referenced by ws_bc_add_function(), and ws_bc_decode(). |
|
|
Definition at line 159 of file wsbc.h. Referenced by add_pragma(), ws_bc_add_pragma_access_domain(), ws_bc_add_pragma_access_path(), ws_bc_add_pragma_user_agent_property(), ws_bc_add_pragma_user_agent_property_and_scheme(), and ws_bc_decode(). |
|
|
Definition at line 108 of file wsbc.h. 00109 {
00110 WS_BC_CONST_TYPE_INT,
00111 WS_BC_CONST_TYPE_FLOAT32,
00112 WS_BC_CONST_TYPE_FLOAT32_NAN,
00113 WS_BC_CONST_TYPE_FLOAT32_POSITIVE_INF,
00114 WS_BC_CONST_TYPE_FLOAT32_NEGATIVE_INF,
00115 WS_BC_CONST_TYPE_UTF8_STRING,
00116 WS_BC_CONST_TYPE_EMPTY_STRING
00117 } WsBcConstantType;
|
|
|
Definition at line 142 of file wsbc.h. 00143 {
00144 WS_BC_PRAGMA_TYPE_ACCESS_DOMAIN,
00145 WS_BC_PRAGMA_TYPE_ACCESS_PATH,
00146 WS_BC_PRAGMA_TYPE_USER_AGENT_PROPERTY,
00147 WS_BC_PRAGMA_TYPE_USER_AGENT_PROPERTY_AND_SCHEME
00148 } WsBcPragmaType;
|
|
|
Definition at line 90 of file wsbc.h. Referenced by compile_stream(). 00091 {
00092 WS_BC_STRING_ENC_ISO_8859_1 = 4,
00093 WS_BC_STRING_ENC_UTF8 = 106
00094 } WsBcStringEncoding;
|
|
||||||||||||
|
Definition at line 951 of file wsbc.c. References WsBcRec::constants, WsBcRec::num_constants, WsBcConstantRec::type, ws_realloc(), WsBc, WsBcConstant, WsBool, and WsUInt16. 00952 {
00953 WsUInt16 i;
00954 WsBcConstant *nc;
00955
00956 /* Do we already have a suitable empty string constant? */
00957 for (i = 0; i < bc->num_constants; i++) {
00958 if (bc->constants[i].type == WS_BC_CONST_TYPE_EMPTY_STRING) {
00959 *index_return = i;
00960 return WS_TRUE;
00961 }
00962 }
00963
00964 /* Must add a new constant. */
00965
00966 nc = ws_realloc(bc->constants,
00967 (bc->num_constants + 1) * sizeof(WsBcConstant));
00968 if (nc == NULL)
00969 return WS_FALSE;
00970
00971 bc->constants = nc;
00972 bc->constants[bc->num_constants].type = WS_BC_CONST_TYPE_EMPTY_STRING;
00973
00974 *index_return = bc->num_constants++;
00975
00976 return WS_TRUE;
00977 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 881 of file wsbc.c. References WsBcRec::constants, WsBcRec::num_constants, WsBcConstantRec::type, WsBcConstantRec::u, WsBcConstantRec::v_float, WS_BC_CONST_TYPE_FLOAT32, ws_realloc(), WsBc, WsBcConstant, WsBool, and WsUInt16. Referenced by ws_expr_linearize(). 00882 {
00883 WsUInt16 i;
00884 WsBcConstant *nc;
00885
00886 /* Do we already have a suitable float32 constant? */
00887 for (i = 0; i < bc->num_constants; i++) {
00888 if (bc->constants[i].type == WS_BC_CONST_TYPE_FLOAT32
00889 && bc->constants[i].u.v_float == value) {
00890 *index_return = i;
00891 return WS_TRUE;
00892 }
00893 }
00894
00895 /* Must add a new constant. */
00896
00897 nc = ws_realloc(bc->constants,
00898 (bc->num_constants + 1) * sizeof(WsBcConstant));
00899 if (nc == NULL)
00900 return WS_FALSE;
00901
00902 bc->constants = nc;
00903 bc->constants[bc->num_constants].type = WS_BC_CONST_TYPE_FLOAT32;
00904 bc->constants[bc->num_constants].u.v_float = value;
00905
00906 *index_return = bc->num_constants++;
00907
00908 return WS_TRUE;
00909 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 850 of file wsbc.c. References WsBcRec::constants, WsBcRec::num_constants, WsBcConstantRec::type, WsBcConstantRec::u, WsBcConstantRec::v_int, WS_BC_CONST_TYPE_INT, ws_realloc(), WsBc, WsBcConstant, WsBool, and WsUInt16. Referenced by ws_expr_linearize(). 00851 {
00852 WsUInt16 i;
00853 WsBcConstant *nc;
00854
00855 /* Do we already have a suitable integer constant? */
00856 for (i = 0; i < bc->num_constants; i++) {
00857 if (bc->constants[i].type == WS_BC_CONST_TYPE_INT
00858 && bc->constants[i].u.v_int == value) {
00859 *index_return = i;
00860 return WS_TRUE;
00861 }
00862 }
00863
00864 /* Must add a new constant. */
00865
00866 nc = ws_realloc(bc->constants,
00867 (bc->num_constants + 1) * sizeof(WsBcConstant));
00868 if (nc == NULL)
00869 return WS_FALSE;
00870
00871 bc->constants = nc;
00872 bc->constants[bc->num_constants].type = WS_BC_CONST_TYPE_INT;
00873 bc->constants[bc->num_constants].u.v_int = value;
00874
00875 *index_return = bc->num_constants++;
00876
00877 return WS_TRUE;
00878 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 912 of file wsbc.c. References WsBcRec::constants, data, WsUtf8StringRec::data, WsUtf8StringRec::len, WsBcRec::num_constants, WsBcConstantRec::type, WsBcConstantRec::u, WsBcConstantRec::v_string, WS_BC_CONST_TYPE_UTF8_STRING, ws_memdup(), ws_realloc(), WsBc, WsBcConstant, WsBool, and WsUInt16. Referenced by ws_bc_add_pragma_access_domain(), ws_bc_add_pragma_access_path(), ws_bc_add_pragma_user_agent_property(), ws_bc_add_pragma_user_agent_property_and_scheme(), ws_expr_linearize(), and ws_pragma_use(). 00914 {
00915 WsUInt16 i;
00916 WsBcConstant *nc;
00917
00918 /* Do we already have a suitable UFT-8 constant? */
00919 for (i = 0; i < bc->num_constants; i++) {
00920 if (bc->constants[i].type == WS_BC_CONST_TYPE_UTF8_STRING
00921 && bc->constants[i].u.v_string.len == len
00922 && memcmp(bc->constants[i].u.v_string.data,
00923 data, len) == 0) {
00924 *index_return = i;
00925 return WS_TRUE;
00926 }
00927 }
00928
00929 /* Must add a new constant. */
00930
00931 nc = ws_realloc(bc->constants,
00932 (bc->num_constants + 1) * sizeof(WsBcConstant));
00933 if (nc == NULL)
00934 return WS_FALSE;
00935
00936 bc->constants = nc;
00937 bc->constants[bc->num_constants].type = WS_BC_CONST_TYPE_UTF8_STRING;
00938 bc->constants[bc->num_constants].u.v_string.len = len;
00939 bc->constants[bc->num_constants].u.v_string.data
00940 = ws_memdup(data, len);
00941 if (bc->constants[bc->num_constants].u.v_string.data == NULL)
00942 return WS_FALSE;
00943
00944 *index_return = bc->num_constants++;
00945
00946 return WS_TRUE;
00947 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||||||||||
|
Definition at line 1056 of file wsbc.c. References code, WsBcFunctionRec::code, WsBcFunctionRec::code_size, WsBcRec::function_names, WsBcRec::functions, WsBcFunctionNameRec::index, name, WsBcFunctionNameRec::name, WsBcFunctionRec::num_arguments, WsBcRec::num_function_names, WsBcRec::num_functions, WsBcFunctionRec::num_locals, ws_memdup(), ws_realloc(), ws_strdup(), WsBc, WsBcFunction, WsBcFunctionName, and WsBool. Referenced by compile_stream(). 01059 {
01060 WsBcFunction *nf;
01061
01062 /* First, add the function to the function pool. */
01063
01064 nf = ws_realloc(bc->functions,
01065 (bc->num_functions + 1) * sizeof(WsBcFunction));
01066 if (nf == NULL)
01067 return WS_FALSE;
01068
01069 bc->functions = nf;
01070 bc->functions[bc->num_functions].num_arguments = num_arguments;
01071 bc->functions[bc->num_functions].num_locals = num_locals;
01072 bc->functions[bc->num_functions].code_size = code_size;
01073 bc->functions[bc->num_functions].code = ws_memdup(code, code_size);
01074
01075 if (bc->functions[bc->num_functions].code == NULL)
01076 return WS_FALSE;
01077
01078 /* Save the index of the function. */
01079 *index_return = bc->num_functions++;
01080
01081 /* For external functions (which have name), add a name entry to the
01082 function name pool. */
01083 if (name) {
01084 WsBcFunctionName *nfn;
01085
01086 nfn = ws_realloc(bc->function_names,
01087 ((bc->num_function_names + 1)
01088 * sizeof(WsBcFunctionName)));
01089 if (nfn == NULL)
01090 return WS_FALSE;
01091
01092 bc->function_names = nfn;
01093 bc->function_names[bc->num_function_names].index = *index_return;
01094 bc->function_names[bc->num_function_names].name = ws_strdup(name);
01095
01096 if (bc->function_names[bc->num_function_names].name == NULL)
01097 return WS_FALSE;
01098
01099 bc->num_function_names++;
01100 }
01101
01102 /* All done. */
01103 return WS_TRUE;
01104 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 981 of file wsbc.c. References add_pragma(), WsBcPragmaRec::index_1, ws_bc_add_const_utf8_string(), WS_BC_PRAGMA_TYPE_ACCESS_DOMAIN, WsBc, WsBcPragma, and WsBool. Referenced by yyparse(). 00983 {
00984 WsBcPragma *p = add_pragma(bc, WS_BC_PRAGMA_TYPE_ACCESS_DOMAIN);
00985
00986 if (p == NULL)
00987 return WS_FALSE;
00988
00989 if (!ws_bc_add_const_utf8_string(bc, &p->index_1, domain, domain_len))
00990 return WS_FALSE;
00991
00992 return WS_TRUE;
00993 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 996 of file wsbc.c. References add_pragma(), WsBcPragmaRec::index_1, ws_bc_add_const_utf8_string(), WS_BC_PRAGMA_TYPE_ACCESS_PATH, WsBc, WsBcPragma, and WsBool. Referenced by yyparse(). 00998 {
00999 WsBcPragma *p = add_pragma(bc, WS_BC_PRAGMA_TYPE_ACCESS_PATH);
01000
01001 if (p == NULL)
01002 return WS_FALSE;
01003
01004 if (!ws_bc_add_const_utf8_string(bc, &p->index_1, path, path_len))
01005 return WS_FALSE;
01006
01007 return WS_TRUE;
01008 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||
|
Definition at line 1011 of file wsbc.c. References add_pragma(), WsBcPragmaRec::index_1, WsBcPragmaRec::index_2, name, name_len, ws_bc_add_const_utf8_string(), WS_BC_PRAGMA_TYPE_USER_AGENT_PROPERTY, WsBc, WsBcPragma, and WsBool. Referenced by yyparse(). 01016 {
01017 WsBcPragma *p = add_pragma(bc, WS_BC_PRAGMA_TYPE_USER_AGENT_PROPERTY);
01018
01019 if (p == NULL)
01020 return WS_FALSE;
01021
01022 if (!ws_bc_add_const_utf8_string(bc, &p->index_1, name, name_len)
01023 || !ws_bc_add_const_utf8_string(bc, &p->index_2, property, property_len))
01024 return WS_FALSE;
01025
01026 return WS_TRUE;
01027 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||||||||||
|
Definition at line 1030 of file wsbc.c. References add_pragma(), WsBcPragmaRec::index_1, WsBcPragmaRec::index_2, WsBcPragmaRec::index_3, name, name_len, ws_bc_add_const_utf8_string(), WS_BC_PRAGMA_TYPE_USER_AGENT_PROPERTY_AND_SCHEME, WsBc, WsBcPragma, and WsBool. Referenced by yyparse(). 01038 {
01039 WsBcPragma *p;
01040
01041 p = add_pragma(bc, WS_BC_PRAGMA_TYPE_USER_AGENT_PROPERTY_AND_SCHEME);
01042
01043 if (p == NULL)
01044 return WS_FALSE;
01045
01046 if (!ws_bc_add_const_utf8_string(bc, &p->index_1, name, name_len)
01047 || !ws_bc_add_const_utf8_string(bc, &p->index_2, property, property_len)
01048 || !ws_bc_add_const_utf8_string(bc, &p->index_3, scheme, scheme_len))
01049 return WS_FALSE;
01050
01051 return WS_TRUE;
01052 }
|
Here is the call graph for this function:

|
|
Definition at line 84 of file wsbc.c. References WsBcRec::string_encoding, ws_calloc(), and WsBc. Referenced by compile_stream(), and ws_bc_decode(). 00085 {
00086 WsBc *bc = ws_calloc(1, sizeof(WsBc));
00087
00088 if (bc == NULL)
00089 return NULL;
00090
00091 bc->string_encoding = string_encoding;
00092
00093 return bc;
00094 }
|
Here is the call graph for this function:

|
|
Definition at line 426 of file wsbc.c. References data, ws_decode_mb_uint32(), ws_free(), and WS_MB_UINT32_MAX_ENCODED_LEN. Referenced by ws_compile_file(), and ws_free_byte_code(). 00427 {
00428 size_t len = WS_MB_UINT32_MAX_ENCODED_LEN;
00429
00430 if (data == NULL)
00431 return;
00432
00433 /* Decode the mb-encoded length so we know how much space it uses. */
00434 (void) ws_decode_mb_uint32(data + 1, &len);
00435
00436 /* Now we can compute the beginning of the array `data'. */
00437 ws_free(data - (WS_MB_UINT32_MAX_ENCODED_LEN - len));
00438 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 457 of file wsbc.c. References WsBcFunctionRec::code, WsBcFunctionRec::code_size, WsBcRec::constants, WsUtf8StringRec::data, data, error(), WsBcRec::function_names, WsBcRec::functions, WsBcFunctionNameRec::index, WsBcPragmaRec::index_1, WsBcPragmaRec::index_2, WsBcPragmaRec::index_3, WsUtf8StringRec::len, WsBcFunctionNameRec::name, WsBcFunctionRec::num_arguments, WsUtf8StringRec::num_chars, WsBcRec::num_constants, WsBcRec::num_function_names, WsBcRec::num_functions, WsBcFunctionRec::num_locals, WsBcRec::num_pragmas, WsBcRec::pragmas, WsBcRec::string_encoding, WsBcPragmaRec::type, WsBcConstantRec::type, WsBcConstantRec::u, WsBcConstantRec::v_float, WsBcConstantRec::v_int, WsBcConstantRec::v_string, ws_bc_alloc(), WS_BC_CONST_EMPTY_STRING, WS_BC_CONST_EXT_ENC_STRING, WS_BC_CONST_FLOAT32, WS_BC_CONST_INT16, WS_BC_CONST_INT32, WS_BC_CONST_INT8, WS_BC_CONST_UTF8_STRING, ws_bc_free(), WS_BC_PRAGMA_ACCESS_DOMAIN, WS_BC_PRAGMA_ACCESS_PATH, WS_BC_PRAGMA_USER_AGENT_PROPERTY, WS_BC_PRAGMA_USER_AGENT_PROPERTY_AND_SCHEME, WS_BC_STRING_ENC_ISO_8859_1, WS_BC_VERSION, ws_calloc(), WS_CHECK_STRING, ws_decode_buffer(), WS_ENC_BYTE, WS_ENC_DATA, WS_ENC_END, WS_ENC_INT16, WS_ENC_INT32, WS_ENC_INT8, WS_ENC_MB_UINT16, WS_ENC_MB_UINT32, WS_ENC_UINT8, ws_fatal(), ws_ieee754_decode_single(), WS_IEEE754_NAN, WS_IEEE754_NEGATIVE_INF, WS_IEEE754_OK, WS_IEEE754_POSITIVE_INF, ws_memdup(), ws_utf8_verify(), WsBc, WsBcConstant, WsBcFunction, WsBcFunctionName, WsBcPragma, WsByte, WsIeee754Result, WsInt16, WsInt32, WsInt8, WsUInt16, WsUInt32, and WsUInt8. Referenced by main(). 00458 {
00459 WsBc *bc = ws_bc_alloc(WS_BC_STRING_ENC_ISO_8859_1);
00460 WsByte b;
00461 WsUInt32 ui32;
00462 WsUInt16 ui16, j;
00463 WsUInt16 ui16b;
00464 WsUInt8 ui8, num_functions, k, l;
00465 WsInt8 i8;
00466 WsInt16 i16;
00467 WsInt32 i32;
00468 WsIeee754Result ieee754;
00469 unsigned char *ucp;
00470 size_t decoded;
00471
00472 /* Decode the byte-code header. */
00473 decoded = ws_decode_buffer(data, data_len,
00474 WS_ENC_BYTE, &b,
00475 WS_ENC_MB_UINT32, &ui32,
00476 WS_ENC_END);
00477
00478 if (!decoded
00479 || b != WS_BC_VERSION
00480 || ui32 != data_len - decoded)
00481 /* This is not a valid (or supported) byte-code header. */
00482 goto error;
00483
00484 WS_UPDATE_DATA;
00485
00486 /* Constant pool. */
00487
00488 decoded = ws_decode_buffer(data, data_len,
00489 WS_ENC_MB_UINT16, &ui16,
00490 WS_ENC_MB_UINT16, &ui16b,
00491 WS_ENC_END);
00492 if (!decoded)
00493 goto error;
00494
00495 bc->string_encoding = ui16b;
00496
00497 bc->constants = ws_calloc(ui16, sizeof(WsBcConstant));
00498 if (bc->constants == NULL)
00499 goto error;
00500 bc->num_constants = ui16;
00501
00502 WS_UPDATE_DATA;
00503
00504 for (j = 0; j < bc->num_constants; j++) {
00505 WsBcConstant *c = &bc->constants[j];
00506
00507 decoded = ws_decode_buffer(data, data_len,
00508 WS_ENC_UINT8, &ui8,
00509 WS_ENC_END);
00510 if (decoded != 1)
00511 goto error;
00512
00513 WS_UPDATE_DATA;
00514
00515 switch (ui8) {
00516 case WS_BC_CONST_INT8:
00517 decoded = ws_decode_buffer(data, data_len,
00518 WS_ENC_INT8, &i8,
00519 WS_ENC_END);
00520 if (decoded != 1)
00521 goto error;
00522
00523 WS_UPDATE_DATA;
00524
00525 c->type = WS_BC_CONST_TYPE_INT;
00526 c->u.v_int = i8;
00527 break;
00528
00529 case WS_BC_CONST_INT16:
00530 decoded = ws_decode_buffer(data, data_len,
00531 WS_ENC_INT16, &i16,
00532 WS_ENC_END);
00533 if (decoded != 2)
00534 goto error;
00535
00536 WS_UPDATE_DATA;
00537
00538 c->type = WS_BC_CONST_TYPE_INT;
00539 c->u.v_int = i16;
00540 break;
00541
00542 case WS_BC_CONST_INT32:
00543 decoded = ws_decode_buffer(data, data_len,
00544 WS_ENC_INT32, &i32,
00545 WS_ENC_END);
00546 if (decoded != 4)
00547 goto error;
00548
00549 WS_UPDATE_DATA;
00550
00551 c->type = WS_BC_CONST_TYPE_INT;
00552 c->u.v_int = i32;
00553 break;
00554
00555 case WS_BC_CONST_FLOAT32:
00556 decoded = ws_decode_buffer(data, data_len,
00557 WS_ENC_DATA, &ucp, (size_t) 4,
00558 WS_ENC_END);
00559 if (decoded != 4)
00560 goto error;
00561
00562 WS_UPDATE_DATA;
00563
00564 ieee754 = ws_ieee754_decode_single(ucp, &c->u.v_float);
00565
00566 switch (ieee754) {
00567 case WS_IEEE754_OK:
00568 c->type = WS_BC_CONST_TYPE_FLOAT32;
00569 break;
00570
00571 case WS_IEEE754_NAN:
00572 c->type = WS_BC_CONST_TYPE_FLOAT32_NAN;
00573 break;
00574
00575 case WS_IEEE754_POSITIVE_INF:
00576 c->type = WS_BC_CONST_TYPE_FLOAT32_POSITIVE_INF;
00577 break;
00578
00579 case WS_IEEE754_NEGATIVE_INF:
00580 c->type = WS_BC_CONST_TYPE_FLOAT32_NEGATIVE_INF;
00581 break;
00582 }
00583
00584 break;
00585
00586 case WS_BC_CONST_UTF8_STRING:
00587 decoded = ws_decode_buffer(data, data_len,
00588 WS_ENC_MB_UINT32, &ui32,
00589 WS_ENC_END);
00590 if (decoded == 0)
00591 goto error;
00592
00593 WS_UPDATE_DATA;
00594
00595 c->type = WS_BC_CONST_TYPE_UTF8_STRING;
00596 c->u.v_string.len = ui32;
00597
00598 decoded = ws_decode_buffer(data, data_len,
00599 WS_ENC_DATA, &ucp, c->u.v_string.len,
00600 WS_ENC_END);
00601 if (decoded != ui32)
00602 goto error;
00603
00604 WS_UPDATE_DATA;
00605
00606 c->u.v_string.data = ws_memdup(ucp, ui32);
00607 if (c->u.v_string.data == NULL)
00608 goto error;
00609
00610 /* Check the validity of the data. */
00611 if (!ws_utf8_verify(c->u.v_string.data, c->u.v_string.len,
00612 &c->u.v_string.num_chars))
00613 goto error;
00614 break;
00615
00616 case WS_BC_CONST_EMPTY_STRING:
00617 c->type = WS_BC_CONST_TYPE_EMPTY_STRING;
00618 break;
00619
00620 case WS_BC_CONST_EXT_ENC_STRING:
00621 ws_fatal("external character encoding not implemented yet");
00622 break;
00623
00624 default:
00625 /* Reserved. */
00626 goto error;
00627 break;
00628 }
00629 }
00630
00631 /* Pragma pool. */
00632
00633 decoded = ws_decode_buffer(data, data_len,
00634 WS_ENC_MB_UINT16, &ui16,
00635 WS_ENC_END);
00636 if (!decoded)
00637 goto error;
00638
00639 bc->pragmas = ws_calloc(ui16, sizeof(WsBcPragma));
00640 if (bc->pragmas == NULL)
00641 goto error;
00642 bc->num_pragmas = ui16;
00643
00644 WS_UPDATE_DATA;
00645
00646 for (j = 0; j < bc->num_pragmas; j++) {
00647 WsBcPragma *p = &bc->pragmas[j];
00648
00649 decoded = ws_decode_buffer(data, data_len,
00650 WS_ENC_UINT8, &ui8,
00651 WS_ENC_END);
00652 if (decoded != 1)
00653 goto error;
00654
00655 WS_UPDATE_DATA;
00656
00657 p->type = ui8;
00658
00659 switch (ui8) {
00660 case WS_BC_PRAGMA_ACCESS_DOMAIN:
00661 decoded = ws_decode_buffer(data, data_len,
00662 WS_ENC_MB_UINT16, &p->index_1,
00663 WS_ENC_END);
00664 if (!decoded)
00665 goto error;
00666
00667 WS_CHECK_STRING(p->index_1);
00668 break;
00669
00670 case WS_BC_PRAGMA_ACCESS_PATH:
00671 decoded = ws_decode_buffer(data, data_len,
00672 WS_ENC_MB_UINT16, &p->index_1,
00673 WS_ENC_END);
00674 if (!decoded)
00675 goto error;
00676
00677 WS_CHECK_STRING(p->index_1);
00678 break;
00679
00680 case WS_BC_PRAGMA_USER_AGENT_PROPERTY:
00681 decoded = ws_decode_buffer(data, data_len,
00682 WS_ENC_MB_UINT16, &p->index_1,
00683 WS_ENC_MB_UINT16, &p->index_2,
00684 WS_ENC_END);
00685 if (!decoded)
00686 goto error;
00687
00688 WS_CHECK_STRING(p->index_1);
00689 WS_CHECK_STRING(p->index_2);
00690 break;
00691
00692 case WS_BC_PRAGMA_USER_AGENT_PROPERTY_AND_SCHEME:
00693 decoded = ws_decode_buffer(data, data_len,
00694 WS_ENC_MB_UINT16, &p->index_1,
00695 WS_ENC_MB_UINT16, &p->index_2,
00696 WS_ENC_MB_UINT16, &p->index_3,
00697 WS_ENC_END);
00698 if (!decoded)
00699 goto error;
00700
00701 WS_CHECK_STRING(p->index_1);
00702 WS_CHECK_STRING(p->index_2);
00703 WS_CHECK_STRING(p->index_3);
00704 break;
00705
00706 default:
00707 goto error;
00708 break;
00709 }
00710
00711 WS_UPDATE_DATA;
00712 }
00713
00714 /* Function pool. */
00715
00716 decoded = ws_decode_buffer(data, data_len,
00717 WS_ENC_UINT8, &num_functions,
00718 WS_ENC_END);
00719 if (decoded != 1)
00720 goto error;
00721
00722 WS_UPDATE_DATA;
00723
00724 /* Function names. */
00725
00726 decoded = ws_decode_buffer(data, data_len,
00727 WS_ENC_UINT8, &ui8,
00728 WS_ENC_END);
00729 if (decoded != 1)
00730 goto error;
00731
00732 WS_UPDATE_DATA;
00733
00734 if (ui8) {
00735 /* We have function names. */
00736 bc->function_names = ws_calloc(ui8, sizeof(WsBcFunctionName));
00737 if (bc->function_names == NULL)
00738 goto error;
00739 bc->num_function_names = ui8;
00740
00741 for (k = 0; k < bc->num_function_names; k++) {
00742 WsBcFunctionName *n = &bc->function_names[k];
00743
00744 decoded = ws_decode_buffer(data, data_len,
00745 WS_ENC_UINT8, &n->index,
00746 WS_ENC_UINT8, &ui8,
00747 WS_ENC_END);
00748 if (decoded != 2)
00749 goto error;
00750
00751 WS_UPDATE_DATA;
00752
00753 decoded = ws_decode_buffer(data, data_len,
00754 WS_ENC_DATA, &ucp, (size_t) ui8,
00755 WS_ENC_END);
00756 if (decoded != ui8)
00757 goto error;
00758
00759 WS_UPDATE_DATA;
00760
00761 n->name = ws_memdup(ucp, ui8);
00762 if (n->name == NULL)
00763 goto error;
00764
00765 /* Check the validity of the name. */
00766
00767 if (!ws_utf8_verify((unsigned char *) n->name, ui8, NULL))
00768 goto error;
00769
00770 /* Just check that the data contains only valid characters. */
00771 for (l = 0; l < ui8; l++) {
00772 unsigned int ch = (unsigned char) n->name[l];
00773
00774 if (('a' <= ch && ch <= 'z')
00775 || ('A' <= ch && ch <= 'Z')
00776 || ch == '_'
00777 || (l > 0 && ('0' <= ch && ch <= '9')))
00778 /* Ok. */
00779 continue;
00780
00781 /* Invalid character in the function name. */
00782 goto error;
00783 }
00784
00785 /* Is the index valid? */
00786 if (n->index >= num_functions)
00787 goto error;
00788 }
00789 }
00790
00791 /* Functions. */
00792
00793 if (num_functions) {
00794 /* We have functions. */
00795 bc->functions = ws_calloc(num_functions, sizeof(WsBcFunction));
00796 if (bc->functions == NULL)
00797 goto error;
00798 bc->num_functions = num_functions;
00799
00800 for (k = 0; k < bc->num_functions; k++) {
00801 WsBcFunction *f = &bc->functions[k];
00802
00803 decoded = ws_decode_buffer(data, data_len,
00804 WS_ENC_UINT8, &f->num_arguments,
00805 WS_ENC_UINT8, &f->num_locals,
00806 WS_ENC_MB_UINT32, &f->code_size,
00807 WS_ENC_END);
00808 if (!decoded)
00809 goto error;
00810
00811 WS_UPDATE_DATA;
00812
00813 decoded = ws_decode_buffer(data, data_len,
00814 WS_ENC_DATA, &ucp, f->code_size,
00815 WS_ENC_END);
00816 if (decoded != f->code_size)
00817 goto error;
00818
00819 WS_UPDATE_DATA;
00820
00821 if (f->code_size) {
00822 /* It is not an empty function. */
00823 f->code = ws_memdup(ucp, f->code_size);
00824 if (f->code == NULL)
00825 goto error;
00826 }
00827 }
00828 }
00829
00830 /* Did we process it all? */
00831 if (data_len != 0)
00832 goto error;
00833
00834 /* All done. */
00835 return bc;
00836
00837 /*
00838 * Error handling.
00839 */
00840
00841 error:
00842
00843 ws_bc_free(bc);
00844
00845 return NULL;
00846 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 132 of file wsbc.c. References WsBcFunctionRec::code, WsBcFunctionRec::code_size, WsBcRec::constants, WsUtf8StringRec::data, data, error(), WsBcRec::function_names, WsBcRec::functions, WsBcFunctionNameRec::index, WsBcPragmaRec::index_1, WsBcPragmaRec::index_2, WsBcPragmaRec::index_3, latin1, WsUtf8StringRec::len, WsBcFunctionNameRec::name, name_len, WsBcFunctionRec::num_arguments, WsBcRec::num_constants, WsBcRec::num_function_names, WsBcRec::num_functions, WsBcFunctionRec::num_locals, WsBcRec::num_pragmas, WsBcRec::pragmas, string, WsBcRec::string_encoding, WsBcPragmaRec::type, WsBcConstantRec::type, WsBcConstantRec::u, WsBcConstantRec::v_float, WsBcConstantRec::v_int, WsBcConstantRec::v_string, WS_BC_CONST_EMPTY_STRING, WS_BC_CONST_EXT_ENC_STRING, WS_BC_CONST_FLOAT32, WS_BC_CONST_INT16, WS_BC_CONST_INT32, WS_BC_CONST_INT8, WS_BC_CONST_TYPE_EMPTY_STRING, WS_BC_CONST_TYPE_FLOAT32, WS_BC_CONST_TYPE_FLOAT32_NAN, WS_BC_CONST_TYPE_FLOAT32_NEGATIVE_INF, WS_BC_CONST_TYPE_FLOAT32_POSITIVE_INF, WS_BC_CONST_TYPE_INT, WS_BC_CONST_TYPE_UTF8_STRING, WS_BC_CONST_UTF8_STRING, WS_BC_MAX_HEADER_LEN, WS_BC_PRAGMA_ACCESS_DOMAIN, WS_BC_PRAGMA_ACCESS_PATH, WS_BC_PRAGMA_TYPE_ACCESS_DOMAIN, WS_BC_PRAGMA_TYPE_ACCESS_PATH, WS_BC_PRAGMA_TYPE_USER_AGENT_PROPERTY, WS_BC_PRAGMA_TYPE_USER_AGENT_PROPERTY_AND_SCHEME, WS_BC_PRAGMA_USER_AGENT_PROPERTY, WS_BC_PRAGMA_USER_AGENT_PROPERTY_AND_SCHEME, WS_BC_STRING_ENC_ISO_8859_1, WS_BC_STRING_ENC_UTF8, WS_BC_VERSION, ws_buffer_append_space(), ws_buffer_init(), ws_buffer_len(), ws_buffer_ptr(), ws_buffer_uninit(), WS_ENC_DATA, WS_ENC_END, WS_ENC_INT16, WS_ENC_INT32, WS_ENC_INT8, WS_ENC_MB_UINT16, WS_ENC_MB_UINT32, WS_ENC_UINT8, ws_encode_buffer(), ws_encode_mb_uint32(), ws_fatal(), ws_ieee754_encode_single(), WS_INT16_MIN, WS_INT8_MIN, WS_PUT_UINT8, ws_utf8_alloc(), ws_utf8_free(), ws_utf8_free_data(), ws_utf8_set_data(), ws_utf8_to_latin1(), WsBc, WsBool, WsBuffer, WsInt16, WsInt8, WsUInt16, WsUInt32, WsUInt8, and WsUtf8String. Referenced by compile_stream(). 00134 {
00135 WsBuffer buffer;
00136 WsUInt32 ui;
00137 unsigned char data[64];
00138 unsigned char *p, *mb;
00139 size_t len;
00140
00141 ws_buffer_init(&buffer);
00142
00143 /* Append space for the header. We do not know yet the size of the
00144 resulting byte-code. */
00145 if (!ws_buffer_append_space(&buffer, NULL, WS_BC_MAX_HEADER_LEN))
00146 goto error;
00147
00148
00149 /* Constants. */
00150
00151 if (!ws_encode_buffer(&buffer,
00152 WS_ENC_MB_UINT16, bc->num_constants,
00153 WS_ENC_MB_UINT16, (WsUInt16) bc->string_encoding,
00154 WS_ENC_END))
00155 goto error;
00156
00157 for (ui = 0 ; ui < bc->num_constants; ui++) {
00158 switch (bc->constants[ui].type) {
00159 case WS_BC_CONST_TYPE_INT:
00160 if (WS_INT8_MIN <= bc->constants[ui].u.v_int
00161 && bc->constants[ui].u.v_int <= WS_INT8_MAX) {
00162 if (!ws_encode_buffer(&buffer,
00163 WS_ENC_UINT8, (WsUInt8) WS_BC_CONST_INT8,
00164 WS_ENC_INT8,
00165 (WsInt8) bc->constants[ui].u.v_int,
00166 WS_ENC_END))
00167 goto error;
00168 } else if (WS_INT16_MIN <= bc->constants[ui].u.v_int
00169 && bc->constants[ui].u.v_int <= WS_INT16_MAX) {
00170 if (!ws_encode_buffer(&buffer,
00171 WS_ENC_UINT8, (WsUInt8) WS_BC_CONST_INT16,
00172 WS_ENC_INT16,
00173 (WsInt16) bc->constants[ui].u.v_int,
00174 WS_ENC_END))
00175 goto error;
00176 } else {
00177 if (!ws_encode_buffer(&buffer,
00178 WS_ENC_UINT8, (WsUInt8) WS_BC_CONST_INT32,
00179 WS_ENC_INT32, bc->constants[ui].u.v_int,
00180 WS_ENC_END))
00181 goto error;
00182 }
00183 break;
00184
00185 case WS_BC_CONST_TYPE_FLOAT32:
00186 case WS_BC_CONST_TYPE_FLOAT32_NAN:
00187 case WS_BC_CONST_TYPE_FLOAT32_POSITIVE_INF:
00188 case WS_BC_CONST_TYPE_FLOAT32_NEGATIVE_INF:
00189 switch (bc->constants[ui].type) {
00190 case WS_BC_CONST_TYPE_FLOAT32:
00191 ws_ieee754_encode_single(bc->constants[ui].u.v_float, data);
00192 p = data;
00193 break;
00194
00195 case WS_BC_CONST_TYPE_FLOAT32_NAN:
00196 p = ws_ieee754_nan;
00197 break;
00198
00199 case WS_BC_CONST_TYPE_FLOAT32_POSITIVE_INF:
00200 p = ws_ieee754_positive_inf;
00201 break;
00202
00203 case WS_BC_CONST_TYPE_FLOAT32_NEGATIVE_INF:
00204 p = ws_ieee754_negative_inf;
00205 break;
00206
00207 default:
00208 ws_fatal("ws_bc_encode(): internal inconsistency");
00209 /* NOTREACHED */
00210 p = NULL; /* Initialized to keep compiler quiet. */
00211 break;
00212 }
00213
00214 if (!ws_encode_buffer(&buffer,
00215 WS_ENC_UINT8, (WsUInt8) WS_BC_CONST_FLOAT32,
00216 WS_ENC_DATA, p, 4,
00217 WS_ENC_END))
00218 goto error;
00219 break;
00220
00221 break;
00222
00223 case WS_BC_CONST_TYPE_UTF8_STRING:
00224 /* Encode the strings as requested. */
00225 switch (bc->string_encoding) {
00226 case WS_BC_STRING_ENC_ISO_8859_1:
00227 {
00228 WsUtf8String *string = ws_utf8_alloc();
00229 unsigned char *latin1;
00230 size_t latin1_len;
00231 WsBool success;
00232
00233 if (string == NULL)
00234 goto error;
00235
00236 /* Create an UTF-8 string. */
00237 if (!ws_utf8_set_data(string,
00238 bc->constants[ui].u.v_string.data,
00239 bc->constants[ui].u.v_string.len)) {
00240 ws_utf8_free(string);
00241 goto error;
00242 }
00243
00244 /* Convert it to latin1. */
00245 latin1 = ws_utf8_to_latin1(string, '?', &latin1_len);
00246
00247 /* We'r done with the UTF-8 string. */
00248 ws_utf8_free(string);
00249
00250 if (latin1 == NULL)
00251 goto error;
00252
00253 /* Encode it. */
00254 success = ws_encode_buffer(
00255 &buffer,
00256 WS_ENC_UINT8,
00257 (WsUInt8) WS_BC_CONST_EXT_ENC_STRING,
00258
00259 WS_ENC_MB_UINT32, (WsUInt32) latin1_len,
00260 WS_ENC_DATA, latin1, latin1_len,
00261
00262 WS_ENC_END);
00263 ws_utf8_free_data(latin1);
00264
00265 if (!success)
00266 goto error;
00267 }
00268 break;
00269
00270 case WS_BC_STRING_ENC_UTF8:
00271 if (!ws_encode_buffer(
00272 &buffer,
00273 WS_ENC_UINT8,
00274 (WsUInt8) WS_BC_CONST_UTF8_STRING,
00275
00276 WS_ENC_MB_UINT32,
00277 (WsUInt32) bc->constants[ui].u.v_string.len,
00278
00279 WS_ENC_DATA,
00280 bc->constants[ui].u.v_string.data,
00281 bc->constants[ui].u.v_string.len,
00282
00283 WS_ENC_END))
00284 goto error;
00285 break;
00286 }
00287 break;
00288
00289 case WS_BC_CONST_TYPE_EMPTY_STRING:
00290 if (!ws_encode_buffer(&buffer,
00291 WS_ENC_UINT8,
00292 (WsUInt8) WS_BC_CONST_EMPTY_STRING,
00293 WS_ENC_END))
00294 goto error;
00295 break;
00296 }
00297 }
00298
00299
00300 /* Pragmas. */
00301
00302 if (!ws_encode_buffer(&buffer,
00303 WS_ENC_MB_UINT16, bc->num_pragmas,
00304 WS_ENC_END))
00305 goto error;
00306
00307 for (ui = 0; ui < bc->num_pragmas; ui++) {
00308 switch (bc->pragmas[ui].type) {
00309 case WS_BC_PRAGMA_TYPE_ACCESS_DOMAIN:
00310 if (!ws_encode_buffer(&buffer,
00311 WS_ENC_UINT8,
00312 (WsUInt8) WS_BC_PRAGMA_ACCESS_DOMAIN,
00313
00314 WS_ENC_MB_UINT16, bc->pragmas[ui].index_1,
00315 WS_ENC_END))
00316 goto error;
00317 break;
00318
00319 case WS_BC_PRAGMA_TYPE_ACCESS_PATH:
00320 if (!ws_encode_buffer(&buffer,
00321 WS_ENC_UINT8,
00322 (WsUInt8) WS_BC_PRAGMA_ACCESS_PATH,
00323 WS_ENC_MB_UINT16, bc->pragmas[ui].index_1,
00324 WS_ENC_END))
00325 goto error;
00326 break;
00327
00328 case WS_BC_PRAGMA_TYPE_USER_AGENT_PROPERTY:
00329 if (!ws_encode_buffer(&buffer,
00330 WS_ENC_UINT8,
00331 (WsUInt8) WS_BC_PRAGMA_USER_AGENT_PROPERTY,
00332 WS_ENC_MB_UINT16, bc->pragmas[ui].index_1,
00333 WS_ENC_MB_UINT16, bc->pragmas[ui].index_2,
00334 WS_ENC_END))
00335 goto error;
00336 break;
00337
00338 case WS_BC_PRAGMA_TYPE_USER_AGENT_PROPERTY_AND_SCHEME:
00339 if (!ws_encode_buffer(
00340 &buffer,
00341 WS_ENC_UINT8,
00342 (WsUInt8) WS_BC_PRAGMA_USER_AGENT_PROPERTY_AND_SCHEME,
00343 WS_ENC_MB_UINT16, bc->pragmas[ui].index_1,
00344 WS_ENC_MB_UINT16, bc->pragmas[ui].index_2,
00345 WS_ENC_MB_UINT16, bc->pragmas[ui].index_3,
00346 WS_ENC_END))
00347 goto error;
00348 break;
00349 }
00350 }
00351
00352
00353 /* Function pool. */
00354
00355 if (!ws_encode_buffer(&buffer,
00356 WS_ENC_UINT8, bc->num_functions,
00357 WS_ENC_END))
00358 goto error;
00359
00360 /* Function names. */
00361
00362 if (!ws_encode_buffer(&buffer,
00363 WS_ENC_UINT8, bc->num_function_names,
00364 WS_ENC_END))
00365 goto error;
00366
00367 for (ui = 0; ui < bc->num_function_names; ui++) {
00368 size_t name_len = strlen(bc->function_names[ui].name);
00369
00370 if (!ws_encode_buffer(&buffer,
00371 WS_ENC_UINT8, bc->function_names[ui].index,
00372 WS_ENC_UINT8, (WsUInt8) name_len,
00373 WS_ENC_DATA, bc->function_names[ui].name, name_len,
00374 WS_ENC_END))
00375 goto error;
00376 }
00377
00378 /* Functions. */
00379
00380 for (ui = 0; ui < bc->num_functions; ui++) {
00381 if (!ws_encode_buffer(&buffer,
00382 WS_ENC_UINT8, bc->functions[ui].num_arguments,
00383 WS_ENC_UINT8, bc->functions[ui].num_locals,
00384 WS_ENC_MB_UINT32, bc->functions[ui].code_size,
00385 WS_ENC_DATA, bc->functions[ui].code,
00386 (size_t) bc->functions[ui].code_size,
00387 WS_ENC_END))
00388 goto error;
00389 }
00390
00391
00392 /* Fix the byte-code header. */
00393
00394 p = ws_buffer_ptr(&buffer);
00395
00396 /* Encode the size of the byte-code excluding the byte-code header. */
00397 mb = ws_encode_mb_uint32(ws_buffer_len(&buffer) - WS_BC_MAX_HEADER_LEN,
00398 data, &len);
00399 memcpy(p + WS_BC_MAX_HEADER_LEN - len, mb, len);
00400
00401 /* Set the byte-code file version information. */
00402 WS_PUT_UINT8(p + WS_BC_MAX_HEADER_LEN - len - 1, WS_BC_VERSION);
00403
00404 /* Calculate the beginning of the bc-array and its size. */
00405 *data_return = p + WS_BC_MAX_HEADER_LEN - len - 1;
00406 *data_len_return = ws_buffer_len(&buffer) - WS_BC_MAX_HEADER_LEN + len + 1;
00407
00408 /* All done. */
00409 return WS_TRUE;
00410
00411
00412 /*
00413 * Error handling.
00414 */
00415
00416 error:
00417
00418 ws_buffer_uninit(&buffer);
00419 *data_return = NULL;
00420 *data_len_return = 0;
00421
00422 return WS_FALSE;
00423 }
|
Here is the call graph for this function:

|
|
Definition at line 97 of file wsbc.c. References WsBcFunctionRec::code, WsBcRec::constants, WsUtf8StringRec::data, WsBcRec::function_names, WsBcRec::functions, WsBcFunctionNameRec::name, WsBcRec::num_constants, WsBcRec::num_function_names, WsBcRec::num_functions, WsBcRec::pragmas, WsBcConstantRec::type, WsBcConstantRec::u, WsBcConstantRec::v_string, ws_free(), WsBc, WsBcConstant, WsUInt16, and WsUInt8. Referenced by compile_stream(), main(), and ws_bc_decode(). 00098 {
00099 WsUInt16 i;
00100 WsUInt8 j;
00101
00102 if (bc == NULL)
00103 return;
00104
00105 /* Free constants. */
00106 for (i = 0; i < bc->num_constants; i++) {
00107 WsBcConstant *c = &bc->constants[i];
00108
00109 if (c->type == WS_BC_CONST_TYPE_UTF8_STRING)
00110 ws_free(c->u.v_string.data);
00111 }
00112 ws_free(bc->constants);
00113
00114 /* Free pragmas. */
00115 ws_free(bc->pragmas);
00116
00117 /* Free function names. */
00118 for (j = 0; j < bc->num_function_names; j++)
00119 ws_free(bc->function_names[j].name);
00120 ws_free(bc->function_names);
00121
00122 /* Free functions. */
00123 for (j = 0; j < bc->num_functions; j++)
00124 ws_free(bc->functions[j].code);
00125 ws_free(bc->functions);
00126
00127 /* Free the byte-code structure. */
00128 ws_free(bc);
00129 }
|
Here is the call graph for this function:
