mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'master' of github.com:triAGENS/AvocadoDB
This commit is contained in:
commit
71ea4eb957
|
@ -25,6 +25,8 @@
|
||||||
/// @author Copyright 2012, triagens GmbH, Cologne, Germany
|
/// @author Copyright 2012, triagens GmbH, Cologne, Germany
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include <BasicsC/logging.h>
|
||||||
|
|
||||||
#include "Ahuacatl/ast-codegen-js.h"
|
#include "Ahuacatl/ast-codegen-js.h"
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -36,7 +38,21 @@
|
||||||
/// @{
|
/// @{
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static char* GetIndexedFunctionName (const size_t funcIndex) {
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief register a function name for later disposal
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static bool RegisterString (TRI_aql_codegen_t* const generator,
|
||||||
|
const char* const name) {
|
||||||
|
assert(generator);
|
||||||
|
|
||||||
|
TRI_PushBackVectorPointer(&generator->_strings, (char*) name);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char* GetIndexedFunctionName (TRI_aql_codegen_t* const generator,
|
||||||
|
const size_t funcIndex) {
|
||||||
char* numberString;
|
char* numberString;
|
||||||
char* functionName;
|
char* functionName;
|
||||||
|
|
||||||
|
@ -46,6 +62,9 @@ static char* GetIndexedFunctionName (const size_t funcIndex) {
|
||||||
}
|
}
|
||||||
|
|
||||||
functionName = TRI_Concatenate2String("f", numberString);
|
functionName = TRI_Concatenate2String("f", numberString);
|
||||||
|
if (functionName) {
|
||||||
|
RegisterString(generator, functionName);
|
||||||
|
}
|
||||||
|
|
||||||
TRI_Free(numberString);
|
TRI_Free(numberString);
|
||||||
|
|
||||||
|
@ -57,7 +76,7 @@ static char* GetNextFunctionName (TRI_aql_codegen_t* const generator) {
|
||||||
|
|
||||||
assert(generator);
|
assert(generator);
|
||||||
|
|
||||||
functionName = GetIndexedFunctionName(++generator->_funcIndex);
|
functionName = GetIndexedFunctionName(generator, ++generator->_funcIndex);
|
||||||
|
|
||||||
return functionName;
|
return functionName;
|
||||||
}
|
}
|
||||||
|
@ -65,9 +84,7 @@ static char* GetNextFunctionName (TRI_aql_codegen_t* const generator) {
|
||||||
static void FreeScope (TRI_aql_codegen_scope_t* const scope) {
|
static void FreeScope (TRI_aql_codegen_scope_t* const scope) {
|
||||||
assert(scope);
|
assert(scope);
|
||||||
|
|
||||||
if (scope->_funcName) {
|
// note: scope->_funcName is freed globally
|
||||||
TRI_Free(scope->_funcName);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scope->_buffer) {
|
if (scope->_buffer) {
|
||||||
TRI_FreeStringBuffer(scope->_buffer);
|
TRI_FreeStringBuffer(scope->_buffer);
|
||||||
|
@ -76,7 +93,9 @@ static void FreeScope (TRI_aql_codegen_scope_t* const scope) {
|
||||||
TRI_Free(scope);
|
TRI_Free(scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
static TRI_aql_codegen_scope_t* CreateScope (const char* const funcName, const TRI_aql_scope_type_e type) {
|
static TRI_aql_codegen_scope_t* CreateScope (TRI_aql_codegen_t* const generator,
|
||||||
|
const char* const funcName,
|
||||||
|
const TRI_aql_scope_type_e type) {
|
||||||
TRI_aql_codegen_scope_t* scope = (TRI_aql_codegen_scope_t*) TRI_Allocate(sizeof(TRI_aql_codegen_scope_t));
|
TRI_aql_codegen_scope_t* scope = (TRI_aql_codegen_scope_t*) TRI_Allocate(sizeof(TRI_aql_codegen_scope_t));
|
||||||
|
|
||||||
if (!scope) {
|
if (!scope) {
|
||||||
|
@ -84,13 +103,19 @@ static TRI_aql_codegen_scope_t* CreateScope (const char* const funcName, const T
|
||||||
}
|
}
|
||||||
|
|
||||||
scope->_funcName = TRI_DuplicateString(funcName);
|
scope->_funcName = TRI_DuplicateString(funcName);
|
||||||
|
if (!scope->_funcName) {
|
||||||
|
FreeScope(scope);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegisterString(generator, scope->_funcName);
|
||||||
scope->_variablePrefix = NULL;
|
scope->_variablePrefix = NULL;
|
||||||
scope->_indent = 0;
|
scope->_indent = 0;
|
||||||
scope->_forLoops = 0;
|
scope->_forLoops = 0;
|
||||||
scope->_type = type;
|
scope->_type = type;
|
||||||
|
|
||||||
scope->_buffer = TRI_CreateStringBuffer();
|
scope->_buffer = TRI_CreateStringBuffer();
|
||||||
if (!scope->_funcName || !scope->_buffer) {
|
if (!scope->_buffer) {
|
||||||
FreeScope(scope);
|
FreeScope(scope);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -104,7 +129,7 @@ static bool StartScope (TRI_aql_codegen_t* const generator, const TRI_aql_scope_
|
||||||
assert(generator);
|
assert(generator);
|
||||||
assert(funcName);
|
assert(funcName);
|
||||||
|
|
||||||
scope = CreateScope(funcName, type);
|
scope = CreateScope(generator, funcName, type);
|
||||||
|
|
||||||
if (!scope) {
|
if (!scope) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -236,7 +261,7 @@ static char* EndScope (TRI_aql_codegen_t* const generator) {
|
||||||
|
|
||||||
assert(scope);
|
assert(scope);
|
||||||
|
|
||||||
funcName = TRI_DuplicateString(scope->_funcName);
|
funcName = scope->_funcName;
|
||||||
|
|
||||||
body = TRI_CreateStringBuffer();
|
body = TRI_CreateStringBuffer();
|
||||||
if (!body) {
|
if (!body) {
|
||||||
|
@ -638,7 +663,6 @@ static void GenerateCode (TRI_aql_codegen_t* const generator,
|
||||||
AppendCode(generator, "(");
|
AppendCode(generator, "(");
|
||||||
GenerateCode(generator, ((TRI_aql_node_expand_t*) node)->_expanded);
|
GenerateCode(generator, ((TRI_aql_node_expand_t*) node)->_expanded);
|
||||||
AppendCode(generator, ")");
|
AppendCode(generator, ")");
|
||||||
TRI_Free(funcName);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AQL_NODE_ASSIGN:
|
case AQL_NODE_ASSIGN:
|
||||||
|
@ -661,7 +685,6 @@ static void GenerateCode (TRI_aql_codegen_t* const generator,
|
||||||
|
|
||||||
AppendCode(generator, funcName);
|
AppendCode(generator, funcName);
|
||||||
AppendCode(generator, "($)");
|
AppendCode(generator, "($)");
|
||||||
TRI_Free(funcName);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AQL_NODE_FILTER:
|
case AQL_NODE_FILTER:
|
||||||
|
@ -686,14 +709,27 @@ static void GenerateCode (TRI_aql_codegen_t* const generator,
|
||||||
break;
|
break;
|
||||||
case AQL_NODE_LIMIT: {
|
case AQL_NODE_LIMIT: {
|
||||||
char* previousFunction;
|
char* previousFunction;
|
||||||
|
char* value;
|
||||||
|
|
||||||
AppendIndent(generator);
|
AppendIndent(generator);
|
||||||
AppendCode(generator, "result.push($);\n");
|
AppendCode(generator, "result.push($);\n");
|
||||||
CloseForLoops(generator);
|
CloseForLoops(generator);
|
||||||
AppendCode(generator, " result = AHUACATL_LIMIT(result, ");
|
AppendCode(generator, " result = AHUACATL_LIMIT(result, ");
|
||||||
AppendCode(generator, TRI_StringInt64(((TRI_aql_node_limit_t*) node)->_offset)); // todo: oom
|
|
||||||
|
value = TRI_StringInt64(((TRI_aql_node_limit_t*) node)->_offset);
|
||||||
|
if (!value) {
|
||||||
|
return; // todo: OOM
|
||||||
|
}
|
||||||
|
RegisterString(generator, value);
|
||||||
|
AppendCode(generator, value);
|
||||||
AppendCode(generator, ", ");
|
AppendCode(generator, ", ");
|
||||||
AppendCode(generator, TRI_StringInt64(((TRI_aql_node_limit_t*) node)->_count)); // todo: oom
|
|
||||||
|
value = TRI_StringInt64(((TRI_aql_node_limit_t*) node)->_count);
|
||||||
|
if (!value) {
|
||||||
|
return; // todo: OOM
|
||||||
|
}
|
||||||
|
RegisterString(generator, value);
|
||||||
|
AppendCode(generator, value);
|
||||||
AppendCode(generator, ");\n");
|
AppendCode(generator, ");\n");
|
||||||
previousFunction = EndScope(generator);
|
previousFunction = EndScope(generator);
|
||||||
|
|
||||||
|
@ -718,7 +754,7 @@ static void GenerateCode (TRI_aql_codegen_t* const generator,
|
||||||
size_t i;
|
size_t i;
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
previousFunction = TRI_DuplicateString(scope->_funcName);
|
previousFunction = scope->_funcName;
|
||||||
// todo: OOM
|
// todo: OOM
|
||||||
|
|
||||||
sortFuncName = GetNextFunctionName(generator);
|
sortFuncName = GetNextFunctionName(generator);
|
||||||
|
@ -1006,6 +1042,8 @@ TRI_aql_codegen_t* TRI_CreateCodegenAql (void) {
|
||||||
|
|
||||||
TRI_InitStringBuffer(&generator->_buffer);
|
TRI_InitStringBuffer(&generator->_buffer);
|
||||||
|
|
||||||
|
TRI_InitVectorPointer(&generator->_strings);
|
||||||
|
|
||||||
TRI_InitVectorPointer(&generator->_scopes);
|
TRI_InitVectorPointer(&generator->_scopes);
|
||||||
if (!StartScope(generator, AQL_SCOPE_RESULT, GetNextFunctionName(generator))) {
|
if (!StartScope(generator, AQL_SCOPE_RESULT, GetNextFunctionName(generator))) {
|
||||||
TRI_FreeCodegenAql(generator);
|
TRI_FreeCodegenAql(generator);
|
||||||
|
@ -1020,11 +1058,23 @@ TRI_aql_codegen_t* TRI_CreateCodegenAql (void) {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void TRI_FreeCodegenAql (TRI_aql_codegen_t* const generator) {
|
void TRI_FreeCodegenAql (TRI_aql_codegen_t* const generator) {
|
||||||
|
size_t i;
|
||||||
|
|
||||||
assert(generator);
|
assert(generator);
|
||||||
|
|
||||||
TRI_DestroyStringBuffer(&generator->_buffer);
|
TRI_DestroyStringBuffer(&generator->_buffer);
|
||||||
TRI_DestroyVectorPointer(&generator->_scopes);
|
TRI_DestroyVectorPointer(&generator->_scopes);
|
||||||
|
|
||||||
|
// free strings
|
||||||
|
i = generator->_strings._length;
|
||||||
|
while (i--) {
|
||||||
|
void* string = generator->_strings._buffer[i];
|
||||||
|
if (string) {
|
||||||
|
TRI_Free(string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TRI_DestroyVectorPointer(&generator->_strings);
|
||||||
|
|
||||||
TRI_Free(generator);
|
TRI_Free(generator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1065,7 +1115,7 @@ char* TRI_GenerateCodeAql (const void* const data) {
|
||||||
TRI_AppendStringStringBuffer(&generator->_buffer, "})();\n");
|
TRI_AppendStringStringBuffer(&generator->_buffer, "})();\n");
|
||||||
|
|
||||||
code = TRI_DuplicateString(generator->_buffer._buffer);
|
code = TRI_DuplicateString(generator->_buffer._buffer);
|
||||||
printf("CODE IS:\n%s\n\n",code);
|
LOG_TRACE("generated code:\n%s\n",code);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRI_FreeCodegenAql(generator);
|
TRI_FreeCodegenAql(generator);
|
||||||
|
|
|
@ -73,6 +73,7 @@ typedef struct TRI_aql_codegen_s {
|
||||||
size_t _funcIndex;
|
size_t _funcIndex;
|
||||||
bool _error;
|
bool _error;
|
||||||
char* _funcName;
|
char* _funcName;
|
||||||
|
TRI_vector_pointer_t _strings;
|
||||||
}
|
}
|
||||||
TRI_aql_codegen_t;
|
TRI_aql_codegen_t;
|
||||||
|
|
||||||
|
|
|
@ -143,27 +143,57 @@ TRI_aql_parse_context_t* TRI_CreateParseContextAql (const char* const query) {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void TRI_FreeParseContextAql (TRI_aql_parse_context_t* const context) {
|
void TRI_FreeParseContextAql (TRI_aql_parse_context_t* const context) {
|
||||||
|
size_t i;
|
||||||
|
|
||||||
assert(context);
|
assert(context);
|
||||||
|
|
||||||
|
// free all remaining scopes
|
||||||
while (context->_scopes._length) {
|
while (context->_scopes._length) {
|
||||||
TRI_EndScopeParseContextAql(context);
|
TRI_EndScopeParseContextAql(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Free nodes
|
|
||||||
TRI_DestroyVectorPointer(&context->_scopes);
|
TRI_DestroyVectorPointer(&context->_scopes);
|
||||||
TRI_DestroyVectorPointer(&context->_nodes);
|
|
||||||
|
// free all strings registered
|
||||||
|
i = context->_strings._length;
|
||||||
|
while (i--) {
|
||||||
|
void* string = context->_strings._buffer[i];
|
||||||
|
|
||||||
|
if (string) {
|
||||||
|
TRI_Free(context->_strings._buffer[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
TRI_DestroyVectorPointer(&context->_strings);
|
TRI_DestroyVectorPointer(&context->_strings);
|
||||||
|
|
||||||
|
// free all nodes registered
|
||||||
|
i = context->_nodes._length;
|
||||||
|
while (i--) {
|
||||||
|
TRI_aql_node_t* node = (TRI_aql_node_t*) context->_nodes._buffer[i];
|
||||||
|
if (node) {
|
||||||
|
if (node->free) {
|
||||||
|
// call node's specific free function
|
||||||
|
node->free(node);
|
||||||
|
}
|
||||||
|
// free node itself
|
||||||
|
TRI_Free(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TRI_DestroyVectorPointer(&context->_nodes);
|
||||||
|
|
||||||
|
// free the stack
|
||||||
TRI_DestroyVectorPointer(&context->_stack);
|
TRI_DestroyVectorPointer(&context->_stack);
|
||||||
|
|
||||||
|
// free query string
|
||||||
if (context->_query) {
|
if (context->_query) {
|
||||||
TRI_Free(context->_query);
|
TRI_Free(context->_query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// free lexer
|
||||||
if (context->_parser) {
|
if (context->_parser) {
|
||||||
Ahuacatllex_destroy(context->_parser->_scanner);
|
Ahuacatllex_destroy(context->_parser->_scanner);
|
||||||
TRI_Free(context->_parser);
|
TRI_Free(context->_parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// free error struct
|
||||||
TRI_DestroyErrorAql(&context->_error);
|
TRI_DestroyErrorAql(&context->_error);
|
||||||
|
|
||||||
TRI_Free(context);
|
TRI_Free(context);
|
||||||
|
|
Loading…
Reference in New Issue