static void qb_initialize_build_environment(qb_build_context *cxt) { USE_TSRM uint32_t i; cxt->compiler_contexts = emalloc(sizeof(qb_compiler_context *) * cxt->function_declaration_count); for(i = 0; i < cxt->function_declaration_count; i++) { qb_compiler_context *compiler_cxt = cxt->compiler_contexts[cxt->compiler_context_count++] = emalloc(sizeof(qb_compiler_context)); qb_initialize_compiler_context(compiler_cxt, cxt->pool, cxt->function_declarations[i], i, cxt->function_declaration_count TSRMLS_CC); // add variables used within function if(!qb_add_variables(compiler_cxt)) { qb_dispatch_exceptions(TSRMLS_C); } // set up function prototypes so the functions can resolved against each other qb_initialize_function_prototype(compiler_cxt); // attach the appropriate translator if(!compiler_cxt->function_declaration->import_path) { qb_php_translator_context *translator_cxt = emalloc(sizeof(qb_php_translator_context)); qb_initialize_php_translator_context(translator_cxt, compiler_cxt TSRMLS_CC); compiler_cxt->translation = QB_TRANSLATION_PHP; compiler_cxt->translator_context = translator_cxt; } else { qb_pbj_translator_context *translator_cxt = emalloc(sizeof(qb_pbj_translator_context)); qb_initialize_pbj_translator_context(translator_cxt, compiler_cxt TSRMLS_CC); compiler_cxt->translation = QB_TRANSLATION_PBJ; compiler_cxt->translator_context = translator_cxt; // load the code into memory and decode the pbj data if(!qb_load_external_code(compiler_cxt, compiler_cxt->function_declaration->import_path) || !qb_decode_pbj_binary(translator_cxt)) { qb_dispatch_exceptions(TSRMLS_C); } } // show the zend/pbj opcodes if turned on if(QB_G(show_source_opcodes)) { qb_printer_context _printer_cxt, *printer_cxt = &_printer_cxt; qb_initialize_printer_context(printer_cxt, compiler_cxt TSRMLS_CC); qb_print_source_ops(printer_cxt); qb_free_printer_context(printer_cxt); } } for(i = 0; i < cxt->compiler_context_count; i++) { qb_compiler_context *compiler_cxt = cxt->compiler_contexts[i]; switch(compiler_cxt->translation) { case QB_TRANSLATION_PHP: { // run an initial pass over the opcode to gather info qb_php_translator_context *translator_cxt = compiler_cxt->translator_context; qb_survey_instructions(translator_cxt); } break; case QB_TRANSLATION_PBJ: { qb_pbj_translator_context *translator_cxt = compiler_cxt->translator_context; qb_survey_pbj_instructions(translator_cxt); } break; } } // display warning and bail out on fatal errors qb_dispatch_exceptions(TSRMLS_C); }
void qb_extract_pbj_info(qb_extractor_context *cxt, int output_type) { qb_pbj_translator_context *translator_cxt = cxt->translator_context; zval path = *cxt->input, *parameters; uint32_t i; zval_copy_ctor(&path); convert_to_string(&path); // load the code into memory qb_load_external_code(cxt->compiler_context, Z_STRVAL(path)); // decode the pbj data qb_decode_pbj_binary(translator_cxt); if(output_type == QB_PBJ_DETAILS) { array_init(cxt->return_value); qb_add_string(cxt->return_value, "vendor", translator_cxt->vendor, -1); qb_add_string(cxt->return_value, "name", translator_cxt->name, translator_cxt->name_length); qb_add_string(cxt->return_value, "displayName", translator_cxt->display_name, -1); qb_add_string(cxt->return_value, "description", translator_cxt->description, -1); qb_add_int(cxt->return_value, "version", translator_cxt->version); parameters = qb_add_array(cxt->return_value, "parameters"); for(i = 0; i < translator_cxt->parameter_count; i++) { qb_pbj_parameter *param = &translator_cxt->parameters[i]; if(param != translator_cxt->out_coord && !param->input_size_name) { zval *param_info = qb_add_array(parameters, NULL); qb_add_string(param_info, "direction", (param->qualifier == PBJ_PARAMETER_OUT) ? "out" : "in", -1); qb_add_string(param_info, "name", param->name, -1); qb_add_string(param_info, "displayName", param->display_name, -1); qb_add_string(param_info, "type", pbj_type_names[param->type], -1); qb_add_string(param_info, "parameterType", param->parameter_type, -1); qb_add_string(param_info, "description", param->description, -1); if(param->qualifier == PBJ_PARAMETER_IN) { qb_add_pbj_value(param_info, "minValue", ¶m->min_value); qb_add_pbj_value(param_info, "maxValue", ¶m->max_value); qb_add_pbj_value(param_info, "defaultValue", ¶m->default_value); } } } for(i = 0; i < translator_cxt->texture_count; i++) { qb_pbj_texture *texture = &translator_cxt->textures[i]; zval *param_info = qb_add_array(parameters, NULL); qb_add_string(param_info, "direction", "in", -1); qb_add_string(param_info, "name", texture->name, -1); qb_add_string(param_info, "displayName", NULL, 0); qb_add_string(param_info, "type", pbj_texture_type_names[texture->channel_count], -1); qb_add_string(param_info, "parameterType", NULL, 0); qb_add_string(param_info, "description", NULL, 0); } } else if(output_type == QB_PBJ_DECLARATION) { const char *pbj_path = Z_STRVAL_P(cxt->input); uint32_t param_count = 0; ZVAL_STRING(cxt->return_value, "/**\n", TRUE); qb_append_string(cxt->return_value, " * %.*s()\t", translator_cxt->name_length, translator_cxt->name); if(translator_cxt->description) { qb_append_string(cxt->return_value, "%s", translator_cxt->description); } if(translator_cxt->vendor) { qb_append_string(cxt->return_value, " (%s)", translator_cxt->vendor); } qb_append_string(cxt->return_value, "\n"); qb_append_string(cxt->return_value, " *\n"); qb_append_string(cxt->return_value, " * @engine\tqb\n"); qb_append_string(cxt->return_value, " * @import\t%s\n", pbj_path); qb_append_string(cxt->return_value, " *\n"); if(translator_cxt->out_pixel) { qb_pbj_parameter *param = translator_cxt->out_pixel; uint32_t channel_count; switch(param->type) { case PBJ_TYPE_FLOAT: channel_count = 1; break; case PBJ_TYPE_FLOAT2: channel_count = 2; break; case PBJ_TYPE_FLOAT3: channel_count = 3; break; case PBJ_TYPE_FLOAT4: channel_count = 4; break; } qb_append_string(cxt->return_value, " * @param\t%s\t$%s\n", pbj_texture_qb_types[channel_count], param->name); } for(i = 0; i < translator_cxt->texture_count; i++) { qb_pbj_texture *texture = &translator_cxt->textures[i]; qb_append_string(cxt->return_value, " * @param\t%s\t$%s\n", pbj_texture_qb_types[texture->channel_count], texture->name); } for(i = 0; i < translator_cxt->parameter_count; i++) { qb_pbj_parameter *param = &translator_cxt->parameters[i]; if(param != translator_cxt->out_coord && param != translator_cxt->out_pixel && !param->input_size_name) { const char *type = pbj_param_qb_types[param->type]; if(param->parameter_type) { if(param->type == PBJ_TYPE_FLOAT2) { if(strcmp(param->parameter_type, "position") == 0) { type = "float32[x,y]"; } } else if(param->type == PBJ_TYPE_FLOAT3) { if(strcmp(param->parameter_type, "colorLAB") == 0) { type = "float32[L,a,b]"; } else if(strcmp(param->parameter_type, "colorRGB") == 0) { type = "float32[r,g,b]"; } } else if(param->type == PBJ_TYPE_FLOAT4) { if(strcmp(param->parameter_type, "colorCMYK") == 0) { type = "float32[c,m,y,k]"; } else if(strcmp(param->parameter_type, "colorRGBA") == 0) { type = "float32[r,g,b,a]"; } } } qb_append_string(cxt->return_value, " * @param\t%s\t$%s", type, param->name); if(param->description) { qb_append_string(cxt->return_value, "\t%s", param->description); } qb_append_string(cxt->return_value, "\n"); } } qb_append_string(cxt->return_value, " *\n"); qb_append_string(cxt->return_value, " * @return\tvoid\n"); qb_append_string(cxt->return_value, " */\n"); qb_append_string(cxt->return_value, "function %.*s(", translator_cxt->name_length, translator_cxt->name); if(translator_cxt->out_pixel) { qb_pbj_parameter *param = translator_cxt->out_pixel; qb_append_string(cxt->return_value, "&$%s", param->name); param_count++; } for(i = 0; i < translator_cxt->texture_count; i++) { qb_pbj_texture *texture = &translator_cxt->textures[i]; if(param_count) { qb_append_string(cxt->return_value, ", "); } qb_append_string(cxt->return_value, "$%s", texture->name); param_count++; } for(i = 0; i < translator_cxt->parameter_count; i++) { qb_pbj_parameter *param = &translator_cxt->parameters[i]; if(param != translator_cxt->out_coord && param != translator_cxt->out_pixel && !param->input_size_name) { if(param_count) { qb_append_string(cxt->return_value, ", "); } qb_append_string(cxt->return_value, "$%s", param->name); } } qb_append_string(cxt->return_value, ") {}\n"); } zval_dtor(&path); }