void Table::pushImplementation(lua_State *L) { SLB_DEBUG_CALL; lua_newtable(L); // an NEW empty table lua_newtable(L); // and its metatable: //---------------------------------------------------------------------- // Set the metatable (empty) to the table to avoid calling __gc on the // table itself. This is new in lua 5.2 lua_pushvalue(L,-1); lua_setmetatable(L,-3); //---------------------------------------------------------------------- lua_newtable(L); // cache lua_pushvalue(L, -1); lua_setfield(L, -3, "__indexCache"); pushMeta(L, &Table::__indexProxy); lua_setfield(L,-3, "__index"); pushMeta(L, &Table::__newindex); lua_setfield(L, -3, "__newindex"); pushMeta(L, &Table::__tostring); lua_setfield(L, -3, "__tostring"); pushMeta(L, &Table::__call); lua_setfield(L, -3, "__call"); pushMeta(L, &Table::__garbageCollector); lua_setfield(L, -3, "__gc"); pushMeta(L, &Table::__eq); lua_setfield(L, -3, "__eq"); lua_pop(L,2); // remove the cache table and metatable }
DMJSON * Parser::parseCode(char* code_char_string, int string_length) { indicator_stack_top = 0; CodeIndicator * indicator = indicator_stack + indicator_stack_top; //current indicator DMJSON * root = this->json_pool->getDMJSON(); root->type = 34; indicator->code = root; indicator->parse_status = 14; DMString * code_string = newDMString(string_length); code_string->copy(code_char_string, string_length); char* char_string = code_string->char_string; char preChar; char localChar = 0; char nextChar; int last_index = 0; int i = -1; int line_number = 0; while (true) { if (i >= string_length) { break; } else { i++; } if (last_index > i) { continue; } preChar = localChar; localChar = char_string[i]; nextChar = char_string[i + 1]; if (localChar == '\n') { line_number++; } if (indicator->parse_status == 51) { //@operator@ if (isOperator(localChar)) { continue; } indicator->end = i; DMString * dm_string = parseDMString(char_string, indicator); dm_string->type = TYPE_CODE_OPERATOR; clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; pushMeta((MemorySpace *) dm_string, indicator); last_index = i; } if (indicator->parse_status == 41) { //"string" int string_state = checkString(preChar, localChar, nextChar); if (string_state == 0 || indicator->flag != string_state || indicator->start + 1 > i) { continue; } if (string_state % 10 == 1) { indicator->end = i; last_index = i + 1; } else if (string_state % 10 == 3) { indicator->end = i - 1; last_index = i + 2; } DMString * dm_string = parseDMString(char_string, indicator); clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; pushMeta((MemorySpace *) dm_string, indicator); continue; } if (indicator->parse_status == 61) { // //comments if (isLineEnd(localChar)) { clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; last_index = i + 2; } else { continue; } } if (isLetter(localChar)) { if (indicator->isInLine == NOT_IN_LINE) { indicator->isInLine = IN_LINE; } if (indicator->isInWord == NOT_IN_WORD) { indicator->isInWord = IN_WORD; } continue; } else { if (indicator->isInWord == IN_WORD && indicator->isInLine == IN_LINE) { if (last_index < i) { MemorySpace * element = parseElement(char_string, last_index, i); pushMeta(element, indicator); } last_index = i + 1; indicator->isInWord = NOT_IN_WORD; } } if (indicator->parse_status != 74) { if (indicator->includer == NULL) { } else if (indicator->includer->type == 80) { DMJSON * last_includer = indicator->includer; indicator_stack_top++; indicator = indicator_stack + indicator_stack_top; indicator->parse_status = 74; indicator->includer = last_includer; indicator->isInLine = IN_LINE; } else if (indicator->includer->type == 33) { DMJSON * last_includer = indicator->includer; indicator_stack_top++; indicator = indicator_stack + indicator_stack_top; indicator->parse_status = 33; indicator->code = last_includer; indicator->isInLine = IN_LINE; } else { } } if (isLineEnd(localChar)) { if (indicator->isInLine == NOT_IN_LINE) { last_index = i + 1; continue; } else { indicator->isInLine = NOT_IN_LINE; } if (indicator->parse_status == 74) { DMJSON * last_expression = indicator->includer; MemorySpace * last_meta = last_expression->get(-1, NOT_DEL); if (last_meta == NULL) { } else if (last_meta->type == TYPE_CODE_OPERATOR) { continue; } clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; MemorySpace * element = resolveExpression(last_expression); pushElement(element, indicator); indicator->includer = NULL; } if (indicator->parse_status == 33) { DMJSON* functionReturn = indicator->code; clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; pushElement(functionReturn->self, indicator); indicator->includer = NULL; } if (indicator->parse_status == 81) { clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; } last_index = i + 1; continue; } if (isBlank(localChar)) { if (indicator->isInWord == NOT_IN_WORD) { last_index = i + 1; continue; } if (indicator->parse_status == 31) { clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; last_index = i + 1; continue; } if (indicator->parse_status == 32) { clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; last_index = i + 1; continue; } if (indicator->parse_status == 33) { clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; last_index = i + 1; continue; } if (indicator->parse_status == 22) { clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; last_index = i + 1; continue; } last_index = i + 1; continue; } if (isSeparator(localChar)) { if (indicator->parse_status == 74) { DMJSON * last_expression = indicator->includer; clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; MemorySpace * element = resolveExpression(last_expression); pushElement(element, indicator); indicator->includer = NULL; } if (indicator->parse_status == 81) { clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; } if (indicator->parse_status == 12) { DMJSON * last_function_definition = indicator->includer; if (last_function_definition == NULL) { } else if (last_function_definition->type == 30) { pushElement(last_function_definition->self, indicator); indicator->includer = NULL; } else { //syntax error } } last_index = i + 1; continue; } if (localChar == ':') { MemorySpace * key = NULL; if (indicator->parse_status == 74) { DMJSON * last_expression = indicator->includer; clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; MemorySpace * element = resolveExpression(last_expression); if (element->type == TYPE_CODE_NAME) { key = element; CodeName * key_name = (CodeName *) key; key_name->nameType = 0x99; } else if (element->type == TYPE_STRING) { key = element; key->type = TYPE_CODE_NAME; CodeName * key_name = (CodeName *) key; key_name->nameType = 0x99; } else { //syntax error } indicator->includer = NULL; last_index = i + 1; } if (key != NULL && (indicator->parse_status == 11 || indicator->parse_status == 21)) { DMKeyValue * key_value = newDMKeyValue(); key_value->key = key; DMJSON * parent = indicator->code; indicator_stack_top++; indicator = indicator_stack + indicator_stack_top; indicator->key_value = key_value; indicator->parse_status = 81; parent->set(-1, key_value->self, NOT_REPLACE); } last_index = i + 1; continue; } int string_state = checkString(preChar, localChar, nextChar); if (0 != string_state) { if (indicator->parse_status != 41) { if (string_state == 12 || string_state == 22) { DMString * dm_string = newDMString(0); pushMeta((MemorySpace *) dm_string, indicator); last_index = i + 1; continue; } indicator_stack_top++; indicator = indicator_stack + indicator_stack_top; indicator->parse_status = 41; indicator->flag = string_state; if (string_state % 10 == 1) { indicator->start = i + 1; } else if (string_state % 10 == 3) { indicator->start = i + 2; } continue; } else { //logic error } } if (localChar == '/' && nextChar == '/') { indicator_stack_top++; indicator = indicator_stack + indicator_stack_top; indicator->parse_status = 61; last_index = i + 1; continue; } if (isBracket(localChar)) { if (localChar == '{') { if (indicator->includer == NULL) { DMJSON* includer = this->json_pool->getDMJSON(); includer->type = 80; indicator->includer = includer; } DMJSON * last_includer = indicator->includer; indicator_stack_top++; indicator = indicator_stack + indicator_stack_top; indicator->start = i; if (last_includer != NULL && last_includer->type == 20) { indicator->parse_status = 12; indicator->code = last_includer; } else if (last_includer != NULL && last_includer->type == 30) { indicator->parse_status = 13; indicator->code = last_includer; } else if (last_includer != NULL && last_includer->type / 10 == 4) { indicator->parse_status = 14; indicator->code = last_includer; } else { indicator->parse_status = 11; DMJSON* json = this->json_pool->getDMJSON(); json->type = 0; indicator->code = json; last_includer->set(-1, json->self, NOT_REPLACE); } last_index = i + 1; continue; } if (localChar == '}') { if (indicator->parse_status == 74) { DMJSON * last_expression = indicator->includer; clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; MemorySpace * element = resolveExpression(last_expression); pushElement(element, indicator); indicator->includer = NULL; } if (indicator->parse_status == 81) { clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; last_index = i + 1; } if (indicator->parse_status / 10 != 1) { //syntax error break; } DMJSON * code = indicator->code; clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; if (indicator->parse_status == 11 && code->type == 0) { } else if (indicator->parse_status == 12 || indicator->parse_status == 13 || indicator->parse_status == 14) { pushElement(code->self, indicator); indicator->includer = NULL; } else if (indicator->parse_status == 74) { clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; } last_index = i + 1; continue; } if (localChar == '[') { if (indicator->includer == NULL) { DMJSON* includer = this->json_pool->getDMJSON(); includer->type = 80; indicator->includer = includer; } CodeIndicator * last_indicator = indicator; DMJSON * last_includer = indicator->includer; indicator_stack_top++; indicator = indicator_stack + indicator_stack_top; indicator->start = i; MemorySpace * last_meta = last_indicator->last_meta; if (last_meta == NULL) { if (last_includer != NULL) { last_meta = last_includer->get(-1, NOT_DEL); } } if (last_meta == NULL) { //21:[json] indicator->parse_status = 21; DMJSON* json = this->json_pool->getDMJSON(); json->type = 0; indicator->code = json; last_includer->set(-1, json->self, NOT_REPLACE); } else if (last_meta->type == TYPE_CODE_KEYWORD) { //has with 22:[enum] in: 21:[json] DMString *last_keyword = (DMString *) last_meta; if (*last_keyword == "with" || *last_keyword == "has") { indicator->parse_status = 22; DMJSON* enumDefinition = this->json_pool->getDMJSON(); enumDefinition->type = 61; indicator->code = enumDefinition; last_includer->set(-1, enumDefinition->self, NOT_REPLACE); } else if (*last_keyword == "in" || *last_keyword == "import") { indicator->parse_status = 21; DMJSON* json = this->json_pool->getDMJSON(); json->type = 0; indicator->code = json; last_includer->set(-1, json->self, NOT_REPLACE); } else { //syntax error break; } } else if (last_meta->type == TYPE_CODE_NAME) { //23:[key|index|selector], indicator->parse_status = 23; DMJSON* selector = this->json_pool->getDMJSON(); selector->type = 71; indicator->code = selector; last_includer->set(-1, selector->self, NOT_REPLACE); } else { //21:[json] indicator->parse_status = 21; DMJSON* json = this->json_pool->getDMJSON(); json->type = 0; indicator->code = json; last_includer->set(-1, json->self, NOT_REPLACE); } last_index = i + 1; continue; } if (localChar == ']') { if (indicator->parse_status == 74) { DMJSON * last_expression = indicator->includer; clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; MemorySpace * element = resolveExpression(last_expression); pushElement(element, indicator); indicator->includer = NULL; } if (indicator->parse_status == 81) { clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; last_index = i + 1; } if (indicator->parse_status / 10 != 2) { //syntax error break; } DMJSON * code = indicator->code; CodeIndicator * last_indicator = indicator; indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; clearCodeIndicator(last_indicator); if (indicator->parse_status == 21 && code->type == 0) { } else if (indicator->parse_status == 12 || indicator->parse_status == 13 || indicator->parse_status == 14) { pushElement(code->self, indicator); indicator->includer = NULL; } else if (indicator->parse_status == 74) { clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; } last_index = i + 1; continue; } if (localChar == '(') { if (indicator->includer == NULL) { DMJSON* includer = this->json_pool->getDMJSON(); includer->type = 80; indicator->includer = includer; } CodeIndicator * last_indicator = indicator; if (last_indicator->parse_status == 33) { last_index = i + 1; continue; } DMJSON * last_includer = indicator->includer; indicator_stack_top++; indicator = indicator_stack + indicator_stack_top; indicator->start = i; if (last_includer != NULL && last_includer->type == 30) { indicator->parse_status = 31; indicator->code = last_includer; } else if (last_includer != NULL && last_includer->type / 10 == 4) { indicator->parse_status = 35; indicator->code = last_includer; // last_includer->set(-1, last_includer->self, NOT_REPLACE); } else if (last_includer != NULL && last_includer->type == 33) { indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; if (indicator->parse_status != 33) { //syntax error break; } } else { MemorySpace * last_meta = last_includer->get(-1, NOT_DEL); if (last_meta != NULL && last_meta->type == TYPE_CODE_NAME) { //function call () if (last_includer->dm_list->length > 0) { CodeName * function_name = (CodeName *) last_includer->get(-1, DEL); if (function_name->nameType != 0x82 || function_name->nameType != 0x83) { function_name->nameType = 0x81; } DMJSON * functionCall = this->json_pool->getDMJSON(); functionCall->type = 32; functionCall->name = (DMString *) function_name; indicator->parse_status = 32; indicator->code = functionCall; last_includer->set(-1, functionCall->self, NOT_REPLACE); } else { //syntax error break; } } else if (last_meta != NULL && last_meta->type == TYPE_JSON) { //Anonymous function definition if (last_includer->dm_list->length > 0) { MemorySpace * function_definition_space = last_includer->get(-1, NOT_DEL); DMJSON * functionDefinition = (DMJSON *) function_definition_space->pointer; if (functionDefinition->type != 30) { //syntax error break; } MemorySpace * name = last_includer->get(-3, NOT_DEL); if (name == NULL && indicator_stack_top >= 2) { CodeIndicator * last_last_indicator = indicator_stack + indicator_stack_top - 2; if (last_last_indicator->parse_status == 81 && last_last_indicator->key_value != NULL) { name = last_last_indicator->key_value->key; } } if (name == NULL) { functionDefinition->name = this->helper->no_name; } else if (name->type == TYPE_JSON) { DMJSON * selector = (DMJSON *) name->pointer; if (selector->type != 71) { //syntax error } DMString * function_name = (DMString *) selector->get(-1, NOT_DEL); if (function_name == NULL) { functionDefinition->name = this->helper->no_name; } else if (function_name->type == TYPE_CODE_NAME || function_name->type == TYPE_STRING) { functionDefinition->name = function_name; } else { functionDefinition->name = this->helper->no_name; } } else if (name->type == TYPE_CODE_NAME) { DMString * function_name = spliteFunctionName((DMString *) name); functionDefinition->name = function_name; } else { //syntax error break; } indicator->parse_status = 74; indicator->includer = functionDefinition; indicator_stack_top++; indicator = indicator_stack + indicator_stack_top; indicator->parse_status = 31; indicator->code = functionDefinition; } else { //syntax error break; } } else { //expression () DMJSON * expression = this->json_pool->getDMJSON(); expression->type = 10; indicator->parse_status = 34; indicator->includer = expression; last_includer->set(-1, expression->self, NOT_REPLACE); } } last_index = i + 1; continue; } if (localChar == ')') { if (indicator->parse_status == 74) { DMJSON * last_expression = indicator->includer; clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; MemorySpace * element = resolveExpression(last_expression); pushElement(element, indicator); indicator->includer = NULL; } CodeIndicator * last_indicator = indicator; indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; if (last_indicator->parse_status == 31) { last_indicator->code->block_start = last_indicator->code->dm_list->length; } else if (last_indicator->parse_status == 32) { } else if (last_indicator->parse_status == 33) { DMJSON* functionReturn = last_indicator->code; pushElement(functionReturn->self, indicator); indicator->includer = NULL; } else if (last_indicator->parse_status == 34) { } else if (last_indicator->parse_status == 35) { last_indicator->code->block_start = last_indicator->code->dm_list->length; } else { //syntax error break; } clearCodeIndicator(last_indicator); last_index = i + 1; continue; } } if (isOperator(localChar)) { if (indicator->parse_status != 51) { indicator_stack_top++; indicator = indicator_stack + indicator_stack_top; indicator->parse_status = 51; indicator->start = i; last_index = i; continue; } } } return root; }
int FuncCallStack::push(ITypeInfo* argType, IHqlExpression* curParam) { unsigned len = 0; char* str; int incsize; int inclen; IValue * paramValue = curParam->queryValue(); Owned<IValue> castParam; if (paramValue) // Not all constants have a paramValue - null, all, constant records etc { castParam.setown(paramValue->castTo(argType)); if(!castParam) { PrintLog("Failed to cast paramValue to argType in FuncCallStack::push"); return -1; } } switch (argType->getTypeCode()) { case type_string: case type_data: getStringFromIValue(len, str, castParam); // For STRINGn, len doesn't need to be passed in. if(argType->getSize() == UNKNOWN_LENGTH) { push(sizeof(unsigned), &len); } push(sizeof(char *), &str); if(numToFree < MAXARGS) { toFree[numToFree++] = str; } break; case type_varstring: getStringFromIValue(len, str, castParam); push(sizeof(char *), &str); if(numToFree < MAXARGS) { toFree[numToFree++] = str; } break; case type_qstring: case type_unicode: case type_utf8: { unsigned argSize = castParam->getSize(); const void * text = castParam->queryValue(); str = (char *)malloc(argSize); memcpy(str, text, argSize); // For STRINGn, len doens't need to be passed in. if(argType->getSize() == UNKNOWN_LENGTH) { len = castParam->queryType()->getStringLen(); push(sizeof(unsigned), &len); } push(sizeof(char *), &str); if(numToFree < MAXARGS) { toFree[numToFree++] = str; } } break; case type_varunicode: UNIMPLEMENTED; case type_real: #ifdef MAXFPREGS if (numFpRegs==MAXFPREGS) { PrintLog("Too many floating point registers needed in FuncCallStack::push"); return -1; } char tempbuf[sizeof(double)]; castParam->toMem(tempbuf); #ifdef FPREG_FIXEDSIZE if (argType->getSize()<=4) fpRegs[numFpRegs++] = *(float *)&tempbuf; else fpRegs[numFpRegs++] = *(double *)&tempbuf; #else // Variable size FP registers as on arm/x64 if (argType->getSize()<=4) fpRegs[numFpRegs].f = *(float *)&tempbuf; else fpRegs[numFpRegs].d = *(double *)&tempbuf; fpSizes[numFpRegs++] = argType->getSize(); #endif break; #else // fall through if no hw regs used for params #endif case type_boolean: case type_int: case type_decimal: case type_date: case type_char: case type_enumerated: case type_swapint: case type_packedint: incsize = argType->getSize(); inclen = align(incsize); assure(inclen); castParam->toMem(stackbuf+sp); memset(stackbuf+sp+incsize, 0, inclen - incsize); sp += inclen; break; case type_row: { if (hasMeta) { try { pushMeta(curParam->queryRecordType()); } catch (IException *E) { ::Release(E); return -1; } } if (curParam->getOperator()==no_null) { // MORE - check type matches MemoryBuffer out; createConstantNullRow(out, curParam->queryRecord()); str = (char *) out.detach(); push(sizeof(char *), &str); if(numToFree < MAXARGS) toFree[numToFree++] = str; } else return -1; break; } case type_record: { try { pushMeta(curParam->queryRecordType()); } catch (IException *E) { ::Release(E); return -1; } break; } default: EclIR::dump_ir(curParam); //code isn't here to pass sets/datasets to external functions.... return -1; } return sp; }