diff options
Diffstat (limited to 'servers/visual/shader_language.cpp')
-rw-r--r-- | servers/visual/shader_language.cpp | 55 |
1 files changed, 41 insertions, 14 deletions
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index 9babc99349..2b61d72f6a 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -571,8 +571,10 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { CharType last_char = str[str.length() - 1]; if (hexa_found) { - //hex integers eg."0xFF" or "0x12AB", etc - NOT supported yet - return _make_token(TK_ERROR, "Invalid (hexadecimal) numeric constant - Not supported"); + //integer(hex) + if (str.size() > 11 || !str.is_valid_hex_number(true)) { // > 0xFFFFFFFF + return _make_token(TK_ERROR, "Invalid (hexadecimal) numeric constant"); + } } else if (period_found || exponent_found || float_suffix_found) { //floats if (period_found) { @@ -621,7 +623,11 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { else tk.type = TK_INT_CONSTANT; - tk.constant = str.to_double(); //won't work with hex + if (hexa_found) { + tk.constant = (double)str.hex_to_int64(true); + } else { + tk.constant = str.to_double(); + } tk.line = tk_line; return tk; @@ -2054,7 +2060,7 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = { //sub-functions //array - { "length", TYPE_INT, { TYPE_VOID }, TAG_ARRAY, false }, + { "length", TYPE_INT, { TYPE_VOID }, TAG_ARRAY, true }, { NULL, TYPE_VOID, { TYPE_VOID }, TAG_GLOBAL, false } @@ -2912,7 +2918,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons tk = _get_token(); if (tk.type == TK_PARENTHESIS_OPEN) { //a function - StringName name = identifier; + const StringName &name = identifier; OperatorNode *func = alloc_node<OperatorNode>(); func->op = OP_CALL; @@ -3769,8 +3775,8 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha nv.sint = -cn->values[i].sint; } break; case TYPE_UINT: { - // FIXME: This can't work on uint - nv.uint = -cn->values[i].uint; + // Intentionally wrap the unsigned int value, because GLSL does. + nv.uint = 0 - cn->values[i].uint; } break; case TYPE_FLOAT: { nv.real = -cn->values[i].real; @@ -3882,6 +3888,11 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui if (tk.type == TK_BRACKET_OPEN) { bool unknown_size = false; + if (VisualServer::get_singleton()->is_low_end() && is_const) { + _set_error("Local const arrays are supported only on high-end platform!"); + return ERR_PARSE_ERROR; + } + ArrayDeclarationNode *node = alloc_node<ArrayDeclarationNode>(); node->datatype = type; node->precision = precision; @@ -3917,6 +3928,12 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui tk = _get_token(); if (tk.type == TK_OP_ASSIGN) { + + if (VisualServer::get_singleton()->is_low_end()) { + _set_error("Array initialization is supported only on high-end platform!"); + return ERR_PARSE_ERROR; + } + tk = _get_token(); if (tk.type != TK_CURLY_BRACKET_OPEN) { @@ -4536,8 +4553,13 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui } p_block->statements.push_back(flow); - if (p_block->block_type == BlockNode::BLOCK_TYPE_CASE || p_block->block_type == BlockNode::BLOCK_TYPE_DEFAULT) { - return OK; + + BlockNode *block = p_block; + while (block) { + if (block->block_type == BlockNode::BLOCK_TYPE_CASE || block->block_type == BlockNode::BLOCK_TYPE_DEFAULT) { + return OK; + } + block = block->parent_block; } } else if (tk.type == TK_CF_DISCARD) { @@ -4585,8 +4607,13 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui } p_block->statements.push_back(flow); - if (p_block->block_type == BlockNode::BLOCK_TYPE_CASE || p_block->block_type == BlockNode::BLOCK_TYPE_DEFAULT) { - return OK; + + BlockNode *block = p_block; + while (block) { + if (block->block_type == BlockNode::BLOCK_TYPE_CASE || block->block_type == BlockNode::BLOCK_TYPE_DEFAULT) { + return OK; + } + block = block->parent_block; } } else if (tk.type == TK_CF_CONTINUE) { @@ -5099,7 +5126,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct if (!expr) return ERR_PARSE_ERROR; - if (expr->type != Node::TYPE_CONSTANT) { + if (expr->type == Node::TYPE_OPERATOR && ((OperatorNode *)expr)->op == OP_CALL) { _set_error("Expected constant expression after '='"); return ERR_PARSE_ERROR; } |